【问题标题】:No loop condition in for and while loopfor 和 while 循环中没有循环条件
【发布时间】:2012-10-20 06:07:21
【问题描述】:
while(cond) // fine
for(;cond;) //fine

但是当我删除条件部分时

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

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

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

【问题讨论】:

  • 编译器知道是因为它们是这样定义的吗?

标签: c loops


【解决方案1】:

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

来自 C11 6.8.5.3:(强调我的)

6.8.5.3 for 语句

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      ...编译器(解析器)如何知道 while 中的空条件为错误,for as Infinite 中的空条件?

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

      这是while 循环的语法:

      while ( expression ) statement
      

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

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

      for语句中每个<em>expression<sub>opt</sub></em>中的下标opt表示对应的表达式是可选的。文本强化了这一点:

      6.8.5.3 for 语句

      ...
      2 clause-1expression-3 都可以省略。省略的 expression-2 被替换为 非零常数。

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

      6.8.5.1 while 语句

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          'while' '('exp ')' 统计数据

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

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

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

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

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

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

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

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

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

          (| 表示或)。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-11-05
            • 1970-01-01
            • 2014-02-11
            • 1970-01-01
            • 2014-02-01
            • 1970-01-01
            • 2020-05-15
            • 2014-03-15
            相关资源
            最近更新 更多