一次移植代碼時關於For循環的發現

  歡迎參與討論,轉載請註明出處。
  本文轉載自:https://musoucrow.github.io/2018/03/12/for_loop/

前言

  今日使用Python移植一份C++實現的算法發生了效果不一致的問題,經過仔細分析後發現問題竟出自For循環,由此引申此文。

詳情

  首先來看看C++的For循環:

int i = 0;

for (i = 0; i < 5; i++) {
    //do something
}

  然後再來看看根據直覺進行移植的Python代碼:

i = 0

for i in range(0, 5):
    # do something

  咋看之下似乎並沒有問題,但若是在循環結束後輸出i值,其結果竟是不一致的(C++爲5,而Python爲4)!在大多數情況下,C++的循環變量並不會在外部定義,所以其生存域僅在For循環之中,這種情況下並不會有什麼問題。然而一旦如此,便代表i肯定要用於後續了,如此結果相差1便可讓整個程序炸掉。
  仔細想來C++和Python的循環實現本就不一致,C++是使用一個邏輯值和兩個表達式展開的,而Python則是一個生成器,且Python的生存域向來獨樹一幟,結果不一致也是理所當然的。可是在憑直覺或未了解過的情況下進行移植時便很容易中招,這便是本文的意義,以示警戒。

其他語言的For循環

  俗話說舉一反三,遇到這種問題自然會想到其他編程語言關於For循環的細節,我便選擇了我日常使用的Lua和C#做了嘗試:

local n = 1

for n=1, 5 do
    --do something
end
int i = 0;

for (i = 0; i < 5; i++) {
    //do something
}

  Lua循環完畢後n的值爲1,可謂相當遵守生存域了(循環是一個域,與外部變量無關)。而C#則是與C++一致,這也是理所當然的,畢竟以上代碼跟C++長得完全一致嘛(估計Java也是如此)。

後記

  仔細想來編程語言之間的循環代碼雖然看起來相似,但實際上他們的具體實現乃至表達式都是有所不同的,可見不可想當然,否則就容易遭遇今日這樣的問題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章