一次移植代码时关于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也是如此)。

后记

  仔细想来编程语言之间的循环代码虽然看起来相似,但实际上他们的具体实现乃至表达式都是有所不同的,可见不可想当然,否则就容易遭遇今日这样的问题了。

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