因为C风格的for循环有太多不确定的地方,这些东西都非常的不直观:
典型的C风格的for循环像这样:
for( initialize; condition; increment ) statement( block);
那么存在这么一大堆问题:
* initialize声明的变量可见性范围是?生命周期是?
* condition在第一次循环结束后还是开始前判断?
* increment在第一次循环前执行还是第一次循环后执行?
* 循环结束后,是先执行increment还是先判断condition?
* initialize是否允许同时初始化多个变量?
* initialize和increment都可以省略,那么condition是否可以省略?省略后是不是等价于true?
这些问题的答案当然都是明确的,但都是完全不直观的。
人生苦短,没事记这些玩意儿干啥?
而反观while循环:
while( condition ) statement( block);
既没有initialize,也没有increment,所以这些问题都不存在:
* initialize声明的变量可见性范围是?生命周期是?
没有initialize,所以不存在这个问题
* condition在第一次循环结束后还是开始前判断?
condition放在statement前面,显然是在第一次循环开始前判断,要在第一次循环结束后判断可以用do...while。
* increment在第一次循环前执行还是第一次循环后执行?
没有increment,所以这个问题不存在
* 循环结束后,是先执行increment还是先判断condition?
因为没有increment,这个问题也不存在
* initialize是否允许同时初始化多个变量?
因为没有initialize,这个问题也不存在
* initialize和increment都可以省略,那么condition是否可以省略?省略后是不是等价于true?
condition显然不能被省略,其他俩压根儿没有。
PS:
statement( block) = statement or statement block,语句或语句块。
另外有人提到,for用分号分隔的三个部分都是语句,这是不对的,condition和increment部分是表达式而不是语句……
再补充一点好了,for循环不讨喜的很重要一个原因我觉得是上不上下不下。
论简洁,当然是while循环最简单,一看就懂,不需要额外的记忆。
如果限定在特定的遍历的场景下,for循环又不像foreach那样舒服,太多细节要自己处理。
唯一可圈可点的地方就是可以限制initialize里面declare的变量的可见范围和生命周期。
但是这又是for的另一个命门,因为只有一个statement,所以没法初始化不同类型的两个变量,或者在没有逗号表达式的语言里面做一些额外的初始化操作。
基本上除了个int i=0也玩不出什么花,increment也是一样,除了i++、i--也很难做点别的事情。如果把要执行的东西放increment又很怪异。
这就是上不上下不下,看起来,很多细节暴露给你可以去处理,但实际用起来,这也用不了,那也用不了。最后发现只适合遍历。
更何况对于C/C++语言程序员来说increment很大程度上就是多余的:
for( int i = 0; i++ < 10; )
有时候觉得,搞个只有两个部分的的for循环更好用,increment除了可以在continue的时候被执行,其实直接写到循环尾部或者头部不一样么?
而新出的语言则直接用别的语法支持遍历,那for循环保留的意义就没了。