C中完整的“for”循环语法是什么?

时间:2008-11-09 21:40:35

标签: c syntax for-loop

在阅读其他人的代码时,我看到了一些非常奇怪的for循环。我一直在尝试在for中搜索C循环的完整语法说明,但这很难,因为单词“for”出现在不相关的句子中,使搜索几乎不可能谷歌有效。

在阅读this thread之后,我想到了这个问题,这让我再次感到好奇。

此处for

for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);

在中间条件下有一个逗号分隔两段代码,这个逗号有什么作用?我理解右边的逗号,因为它同时生成a>>=1b<<=1

但是在循环退出条件下,会发生什么?它会在p==0a==1或两者都发生时退出吗?

如果有人能帮助我理解这一点并且可能指向完整的for循环语法描述,那就太棒了。

6 个答案:

答案 0 :(得分:131)

逗号不包​​含for循环;它是逗号运算符。

x = (a, b);

首先执行a,然后执行b,然后将x设置为b的值。

for语法为:

for (init; condition; increment)
    ...

在某种程度上(暂时忽略continuebreak)相当于:

init;
while (condition) {
    ...
    increment;
}

所以你的for循环示例是(再次忽略continuebreak)等效于

p=0;
while (p+=(a&1)*b,a!=1) {
    ...
    a>>=1,b<<=1;
}

其行为就像它一样(再次忽略continuebreak):

p=0; 
while (true) {
    p+=(a&1)*b;
    if (a == 1) break;
    ...
    a>>=1;
    b<<=1;
}

for循环的两个额外细节,它们不是简单转换为上面的while循环:

  • 如果省略该条件,则始终为true(除非breakgoto或其他内容破坏循环,否则会导致无限循环。
  • continue就像是在增量之前转移到标签一样,不像while循环中的continue会跳过增量。

此外,有关逗号运算符的重要细节:它是一个序列点,如&&||(这就是为什么我可以将它拆分为单独的语句并保持其含义完整)。< / p>


C99

的变化

C99标准引入了本解释中前面未提及的几个细微差别(这对C89 / C90非常有用)。

首先,所有循环本身都是块。有效地,

for (...) { ... }

本身包裹在一对大括号中

{
for (...) { ... }
}

标准说:

  

ISO / IEC 9899:1999§6.8.5迭代语句

     

¶5迭代语句是一个块,其范围是其范围的严格子集   封闭的。循环体也是一个块,其范围是范围的严格子集   迭代语句。

这也在基本原理中用额外的括号组来描述。

其次,C99中的init部分可以是(单个)声明,如

for (int i = 0; i < sizeof(something); i++) { ... }

现在,'围绕循环的'块自成一体;它解释了为什么变量i无法在循环外访问。您可以声明多个变量,但它们必须都是相同的类型:

for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }

标准说:

  

ISO / IEC 9899:1999§6.8.5.3for语句

     

声明

for ( clause-1 ; expression-2 ; expression-3 ) statement
     

表现如下:表达式表达式-2是控制表达式   在每次执行循环体之前进行评估。表达式-3表达式为   在每次执行循环体后评估为void表达式。如果第1条是a   声明,它声明的任何变量的范围是声明的剩余部分   整个循环,包括其他两个表达式;它是按执行顺序到达的   在第一次评估控制表达之前。如果子句-1是表达式,那么它是   在第一次评估控制表达之前评估为空表达。 133)

     

可以省略子句-1和表达式-3。省略的表达式-2由a替换   非零常数。

     

133)因此,第1节指定循环的初始化,可能声明一个或多个变量用于   循环;控制表达式expression-2指定在每次迭代之前进行的评估,   这样循环的执行一直持续到表达式比较等于0;和表达-3   指定每次迭代后执行的操作(例如递增)。

答案 1 :(得分:8)

逗号只是分隔两个表达式,并且在C中允许正常表达式的任何地方都有效。这些按从左到右的顺序执行。最右边表达式的值是整个表达式的值。

for循环由三部分组成,其中任何一部分也可能是空的;一个(第一个)在开始时执行,一个(第三个)在每次迭代结束时执行。这些部分通常分别初始化和递增计数器;但他们可以做任何事情。

第二部分是在每次执行开始时执行的测试。如果测试结果为false,则循环中止。这就是它的全部内容。

答案 2 :(得分:5)

C style for循环包含三个表达式:

for (initializer; condition; counter) statement_or_statement_block;
  • 当循环开始时,初始化程序运行一次。
  • 在每次迭代之前检查条件。循环运行的时间与它的计算结果一样长。
  • 计数器在每次迭代后运行一次。

这些部分中的每一部分都可以是您编写循环语言的有效表达式。这意味着它们可以更具创造性地使用。你想要事先做的任何事情都可以进入初始化程序,你想要做的任何事情都可以进入条件或计数器,直到循环没有正文的程度。

为实现这一点,逗号运算符非常方便。它允许您将表达式链接在一起以形成单个新表达式。大多数情况下,它在for循环中以这种方式使用,逗号运算符的其他含义(例如值赋值注意事项)起着次要的作用。

即使你可以通过创造性地使用语法来做聪明的事情 - 我会保持清醒,直到我找到真的这样做的理由。使用for循环播放代码高尔夫使代码更难以阅读和理解(和维护)。

维基百科也有一个不错的article on the for loop

答案 3 :(得分:2)

for循环中的所有内容都是可选的。我们可以初始化多个变量,我们可以检查多个条件,我们可以使用逗号运算符迭代多个变量。

以下for循环将带您进入无限循环。检查条件时要小心。

for(;;) 

答案 4 :(得分:0)

Konrad提到了我想重复的关键点:最右边的表达式的值是整个表达式的值。

当我在for循环的“条件”部分中放入两个测试时,Gnu编译器声明了这个警告

warning: left-hand operand of comma expression has no effect

我真正想要的“条件”是两个带有“&amp;&amp;”的测试之间。根据康拉德的声明,只有逗号右边的测试才会影响条件。

答案 5 :(得分:-1)

for循环执行(;;)

的特定时间

for循环的syntex

有(;;)

OR

for(initializer; condition; counter)

例如(rmv = 1; rmv&lt; = 15; rmv ++)

执行15次for block

1.首先初始化值因为启动值

(例如)rmv = 1或rmv = 2

2.第二个语句是测试条件是真还是假,条件为真时间执行for循环且条件为false终止为块,

例如i = 5; i <= 10条件为真

i=10;i<10 the condition is false terminate for block,

3.第三个是递增或递减

(例如)rmv ++或++ rmv