10
while(cond) // fine
for(;cond;) //fine

但是当我删除条件部分时

while() //syntax compilation error 
for(;;) //Infinite loop

这些循环是如何在内部实现的?或者,编译器(解析器)如何知道其中的空条件while是错误的并且for是无限的?

我没有特别找到任何关于这个的东西,我认为像我这样的人(他们是初学者)在 C 中可能有同样的困惑

4

5 回答 5

12

该标准要求将省略的for循环条件替换为非零常量:

C11 6.8.5.3开始:(强调我的)

6.8.5.3 for 语句

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

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

由于循环没有这样的要求while(如果省略条件),我相信它留给编译器的实现。

于 2012-10-30T20:24:41.723 回答
3

没有技术原因可以解释为什么一个有效而另一个无效。这是语言设计者的人为因素考虑。他们觉得无限循环 usingfor (;;)while (). 他们可能受到了 ALGOL(一种穴居人使用的语言)的影响。

于 2012-10-30T20:11:31.963 回答
3

...编译器(解析器)如何知道 while 中的空条件是错误而 for 是无限的?

因为语言定义在语法(语法)和语义上都指定了它。

这是while循环的语法:

while ( expression ) statement

这是循环的语法for(截至C2011):

for ( expressionopt ; expressionopt ; expressionopt ) statement
for ( declaration expressionopt ; expressionopt ) statement

语句中 each的下标opt表示对应的表达式是可选的。文本强化了这一点:expressionoptfor

6.8.5.3 for 语句

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

相比之下,该while语句的控制表达式没有标记为可选,这在文本中也得到了加强:

6.8.5.1 while 语句

1 控制表达式的计算发生在每次执行循环体之前。

没有太多空间可以解释控制表达式可以省略。

于 2012-10-30T21:44:59.290 回答
2

确定程序语法和语义正确性的条件被编码为语言语法。语言语法是由语言创造者制定的,它们决定了语言的外观,就像在 C 的情况下一样。我想背后的基本直觉for(;;)while(1),任何部分都for(;;)可以省略,尽管while(1)对于创建无限循环来说完全足够了,而while()对于一个狭窄的案例来说,这将是一个骇人听闻的角落案例。

于 2012-10-30T20:17:33.600 回答
2

它是 C 语法的一部分。每种编程语言都有其形式语法规范(这里是BNF 中的 C 形式语法- 即在语法上什么是正确的,什么是不正确的。在 C 形式语法中,您可以看到while必须看起来像:

'while' '(' exp ')' 统计

单引号(终端符号)中的单词/符号是强制性的:'while'、'(' 和 ')'。不带引号的词(非终结符号)也是在形式语法中指定的东西。如果你分析 C 形式语法,你会发现 exp不可能nothing。另一方面,如果您查看for您会看到它可能看起来像:

'for' '(' exp ';' exp ';' exp ')' 统计

| 'for' '(' exp ';' exp ';' ')' 统计

| 'for' '(' exp ';' ';' exp ')' 统计

| 'for' '(' exp ';' ';' ')'stat

| 'for' '(' ';' exp ';' exp ')' 统计

| 'for' '(' ';' exp ';' ')'stat

| 'for' '(' ';' ';' exp ')' 统计

| 'for' '(' ';' ';' ')' 统计

(| 表示或)。

当您编译程序时,词法分析器(编译器的一部分)会检查您的代码在语法上是否正确(即符合形式语法)并根据源代码执行其他操作。

于 2012-10-30T20:47:44.513 回答