欢迎参与讨论,转载请注明出处。
本文转载自: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也是如此)。
后记
仔细想来编程语言之间的循环代码虽然看起来相似,但实际上他们的具体实现乃至表达式都是有所不同的,可见不可想当然,否则就容易遭遇今日这样的问题了。