5

可能重复:
for 和 while 循环中没有循环条件

为什么for-loop允许的条件为空?例如

for (;;)

编译得很好。为什么这个空表达式true的计算结果如下

if () {}
while () {}

两者都会失败吗?我想知道是否/为什么for-loop这种情况的例外。

4

2 回答 2

10

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

这些是迭代语句

while ( 表达式 ) 语句

do 语句 while ( 表达式 ) ;

for ( 表达式 [opt] ; 表达式 [opt] ; 表达式 [opt] ) 语句

for ( 声明表达式 [opt] ; 表达式 [opt] ) 语句

while 循环被设计为在每次执行循环之前评估控制表达式,而 do 循环被设计为在每次执行之后进行评估。

for 循环被设计为更复杂的迭代语句。

6.8.5.3 for 语句

该声明

for ( 子句 1 ; 表达式 2 ; 表达式 3 ) 语句

行为如下: 表达式 expression-2 是在每次执行循环体之前计算的控制表达式。每次执行循环体后,表达式 expression-3 被评估为 void 表达式。如果 Clause-1 是一个声明,它声明的任何标识符的范围是声明的其余部分和整个循环,包括其他两个表达式;它在控制表达式的第一次求值之前按执行顺序到达。如果clause-1 是一个表达式,它在控制表达式的第一次计算之前被计算为一个空表达式。

子句 1 和表达式 3 都可以省略。省略的表达式 2 被非零常量替换。

该规范允许省略表达式 2,即循环的条件,并用一个非零常量代替。这意味着 for 循环将无限期地继续执行。

这对于允许使用简单的语法进行无限迭代很有用。

for(int i = 0;;i++) { //do stuff with i }

这比编写一个在循环外声明变量然后在循环内递增的 while(1) 循环要简单得多。

然后,for 循环规范继续允许您省略第 1 句,以便您可以在别处声明或初始化变量,并且可以省略第 3 表达式,以便在每个循环完成时不需要评估任何表达式。

for 循环是一种特殊情况。while 循环和 do 循环是严格的并且需要一个表达式,但 for 循环是一个灵活的迭代语句。

于 2012-11-13T18:46:17.297 回答
5

我无法给出明确的答案,但我的猜测是,这是因为在for循环的情况下,存在三种不同的表达式,根据循环,您可能需要也可能不需要使用其中的每一个。

在这种if情况下,如果没有表达,那就没有意义了;它需要始终表现得好像表达式是真还是假,因此仅相当于其中一个子句。在这种while情况下,将对 进行有意义的解释while () { },即评估为while (1) { }(给您一个可以用 打破的循环break),但我想省略该单个字符的好处不值得麻烦。

但是,在for循环的情况下,有三种不同的表达式,可能需要也可能不需要。例如,如果你想在每个循环中初始化和增加一些东西,但要break用来跳出循环,你可以写for (i = 0; ; ++i),或者如果你只是想要测试和增加,因为你的变量已经初始化了,你可以写for (; i > 0; --i). 鉴于根据您的循环,这些表达式中的每一个都可能不是必需的,让您为所有不使用的内容填写占位符似乎有点麻烦;并且为了一致性,而不是要求其中一个占位符,它们都是可选的,如果省略,则条件被认为是一个恒定的非零值。

当然,有时很容易将过多的意图解读为设计决策。有时,给定标准的原因很简单,就是它在第一个实现中是如何实现的,而其他人只是复制了它。例如,请参阅Rob Pike 对为什么以 开头的文件.在 Unix 中隐藏的解释;这不是由于深思熟虑的设计决定,而仅仅是因为有人在编写时走捷径ls并且不想每次都显示.和目录条目。..

于 2012-11-13T18:53:33.913 回答