最近看C++ Primer,发现了声明语句竟然可以被用在while的condition中,于是稍作整理,得此博文。
一. for与init-statement
大家都知道for循环是完全可以初始化变量的。for的范式如下所示:
for (init-statement; condition; expression) { /* Do something... */ }
其中,我们的init-statement中定义的变量,完全可以带入我for的block中
e.g.
for (int i = 1; i <= 10; ++i) {
// 输出1~10之间的整数,每一个占一行
std::cout << i << " ";
}
值得注意的是,for循环中的3个statements执行的顺序:
- init-statement只在循环最开始的时候执行一次。
- condition在每次循环开始的时候执行。
- expression在每次循环结束后执行。
这样就保证了不会出现重复定义的error。
for循环,唯一要讲的就是: for的block中定义的变量,会在本次循环结束后无效;同时,进入下一次循环中(如果有的话)又会被重新定义。
二. while与init-statement
虽然while语句中的condition需要一个值,但是init-statement显然没有返回值(即便有,也没有意义),却仍然可以用在condition中。In other words:
while (int i = 1) { /* Do somethings */ }
这样的语句是合法的。
值得注意的是:当且仅当i被初始化为0时,才不进入循环体。
这个建议大家自己尝试,这里就不放图了。
还有就是condition和init-statement共享一个scope:
当然了,从上图还可以看出——当跳出while的block时,condition中定义的变量生命周期终止。
另外,每次循环结束,condition中定义的变量都会被废弃;但在下一次循环(如果有的话),会被重新声明。
三. do…while与init-statement
直接上结论——do…while不允许在condition使用init-statement;
而且,block和scope并不共享一个scope;
// do...while范式
do {
/* Do something */
} while (condition);
这就导致了:
- block中定义的变量无法在condition中使用,因为两种不是同一个scope;
- condition中定义的变量也无法在block中使用。因为根本就不允许定义变量。
所以do…while中的condition中所要用到的变量,只能在do…while块之前声明了。
四. C++ vs C
我之前写的,对于某些专攻C++的人来说,可能过于基础,但是我想说得是,while循环中使用init-statement,只是C++的feature。
可以看我文件的后缀名(.c,而且main的参数也遵循了C中的void)。可以看出C和C++在这基础上表现不同。
至于为什么C++会添加这一种特性,我还不太清楚——存在即合理,希望高人指点。
五. summary
本文总结了loop statement和init-statement之间的关系。最后给出了C与C++之间的一个重要区别。
针对for语句:
- 它有专门的init-statement,只初始化一次。
- 对于block中初始化的变量,在本次循环结束后无效,但在下一次循环中又被重新声明。
针对while语句:
- condition和block共享一个scope。
- 但是while没有特定的初始化语句,所以无论在哪里初始化的变量都遵循for中的第二个特性。
- 变量初始化为非0值,进入block;为0则不进入block
针对do…while:
由于condition和block不共享同一个scope,故不能(也不合法)在condition中使用init-statement;只能在do…while之前才行。