while(cond) // fine
for(;cond;) //fine
但是当我删除条件部分时
while() //syntax compilation error
for(;;) //Infinite loop
这些循环是如何在内部实现的?
或者说,编译器(解析器)如何知道while
中的空条件是错误的,而在for
中是无限的?我没有找到关于这个问题的特别内容,我认为像我一样(初学者)的C语言使用者可能会有同样的困惑。
while
循环的语法:<strong>while (</strong> <em>expression</em> <strong>)</strong> <em>statement</em>
下面是一个for循环的语法(截至C2011):
<strong>for (</strong> <em>expression<sub>opt</sub></em> <strong>;</strong> <em>expression<sub>opt</sub></em> <strong>;</strong> <em>expression<sub>opt</sub></em> <strong>)</strong> <em>statement</em>
<strong>for (</strong> <em>declaration expression<sub>opt</sub></em> <strong>;</strong> <em>expression<sub>opt</sub></em> <strong>)</strong> <em>statement</em>
expressionopt
中的下标opt表示相应的表达式是可选的。这一点在以下文本中得到了强化:
相比之下,while语句的控制表达式没有被标记为可选,这也在以下文本中得到了强化:6.8.5.3 for语句
...
2 clause-1和expression-3都可以省略。省略的expression-2将被替换为非零常量。
在这里没有太多解释控制表达式可以省略的空间。6.8.5.1 while语句
1 在执行循环体之前,对控制表达式进行评估。
没有技术原因可以解释为什么一个有效而另一个无效。这是语言设计者的人类因素考虑。他们认为使用 for (;;)
的无限循环比使用 while ()
更有意义。他们可能受到早期语言 ALGOL 的影响。
for(;;)
和while(1)
背后的基本直觉是,for(;;)
的任何部分都可以省略,而while(1)
完全足够创建无限循环,然而while()
只是一个狭窄情况的hacky角落。单引号中的单词/符号(终端符号)是必需的:'while'、'('和')'。 非引用的单词(非终端符号)也在正式语法中指定了。如果你分析了C语言的正式语法,就会发现exp不能为nothing。另一方面,如果你看看for,就会发现它可以像下面这样:'while' '(' exp ')' stat
(|表示OR)。'for' '(' exp ';' exp ';' exp ')' stat
| 'for' '(' exp ';' exp ';' ')' stat
| 'for' '(' exp ';' ';' exp ')' stat
| 'for' '(' exp ';' ';' ')'stat
| 'for' '(' ';' exp ';' exp ')' stat
| 'for' '(' ';' exp ';' ')'stat
| 'for' '(' ';' ';' exp ')' stat
| 'for' '(' ';' ';' ')' stat