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

在阅读其他人的代码时,我已经看到一些非常奇怪的for循环。 我一直在尝试在C中为a==1循环搜索完整的语法说明,但是这非常困难,因为单词“ for”出现在无关的句子中,这使得搜索对于Google几乎是不可能的。

阅读此主题后,我想到了这个问题,这让我再次感到好奇。

for在这里:

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

在中间条件下,有一个逗号分隔两段代码,这个逗号是做什么的? 我理解右边的逗号是fora==1

但是在循环退出条件下,会发生什么? 它是否在fora==1或同时发生时退出?

如果有人能帮助我理解这一点,或者使我指向完整的for循环语法说明,那就太好了。

fmsf asked 2019-10-07T00:32:13Z
6个解决方案
130 votes

逗号不排除for循环; 它是逗号运算符。

x = (a, b);

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

for语法为:

for (init; condition; increment)
    ...

这有点(现在忽略for ( clause-1 ; expression-2 ; expression-3 ) statement ||)等效于:

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

因此,您的for循环示例(再次忽略for ( clause-1 ; expression-2 ; expression-3 ) statement ||)等效于

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

哪个看起来像(再次忽略for ( clause-1 ; expression-2 ; expression-3 ) statement ||):

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

for循环的两个额外细节,不在上面的while循环的简化转换中:

  • 如果省略该条件,则始终为for ( clause-1 ; expression-2 ; expression-3 ) statement (导致无限循环,除非||goto或其他中断循环)。
  • for ( clause-1 ; expression-2 ; expression-3 ) statement 的行为就像是转到增量之前的标签一样,而||在while循环中会跳过增量。

此外,还有一个有关逗号运算符的重要细节:它是一个序列点,例如for ( clause-1 ; expression-2 ; expression-3 ) statement ||(这就是为什么我可以将其拆分为单独的语句并保持其含义完整的原因)。


C99的变化

C99标准引入了一些在此解释中未提及的细微差别(对于C89 / C90非常好)。

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

for (...) { ... }

本身用大括号包裹

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

标准说:

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

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

在基本原理中也用额外的花括号进行了描述。

其次,C99中的for ( clause-1 ; expression-2 ; expression-3 ) statement 部分可以是一个(单个)声明,例如

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

现在,“环绕循环的块”变成了自己。 它解释了为什么不能在循环外部访问变量for ( clause-1 ; expression-2 ; expression-3 ) statement 。 您可以声明多个变量,但它们都必须具有相同的类型:

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

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

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

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

CesarB answered 2019-10-07T00:35:09Z
8 votes

逗号仅分隔两个表达式,并且在C中允许使用正则表达式的任何位置都有效。 这些从左到右依次执行。 最右边的表达式的值是整个表达式的值。

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

第二部分是在每次执行开始时执行的测试。 如果测试得出false,则循环中止。 这里的所有都是它的。

Konrad Rudolph answered 2019-10-07T00:35:49Z
5 votes

循环的C样式包含三个表达式:

for (initializer; condition; counter) statement_or_statement_block;
  • 循环开始时,初始化程序运行一次。
  • 在每次迭代之前检查条件。 只要计算结果为true,循环就会运行。
  • 计数器在每次迭代后运行一次。

这些部分中的每一个都可以是使用您编写循环所用语言有效的表达式。这意味着它们可以更有创造性地使用。 您想要做的任何事都可以进入初始化器,介于两者之间的任何事都可以进入条件或计数器,直到循环不再有主体为止。

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

即使您可以通过创造性地使用语法来做聪明的事情-在我找到这样做的充分理由之前,我都会避免这样做。 使用for循环玩代码高尔夫会使代码难以阅读和理解(和维护)。

维基百科在for循环上也有一篇不错的文章。

Tomalak answered 2019-10-07T00:37:01Z
2 votes

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

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

for(;;) 
GEOCHET answered 2019-10-07T00:37:34Z
0 votes

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

当我在for循环的“ condition”部分中放置两个测试时,一个Gnu编译器发出了此警告

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

我真正想要的“条件”是两个测试之间有一个“ &&”。 根据Konrad的声明,只有逗号右边的测试会影响条件。

Bob answered 2019-10-07T00:38:14Z
-1 votes

for循环在特定时间执行for(;;)

for循环的语法

对于(;;)

要么

用于(初始化;条件;计数器)

例如(rmv = 1; rmv <= 15; rmv ++)

执行15次

1.首先初始化值,因为开始值

(例如)rmv = 1或rmv = 2

2.第二条语句测试条件为真或为假,条件为真的次数。执行for循环,条件为假。

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

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

3.第三个是递增或递减

(例如)rmv ++或++ rmv

R.M.VIVEK ARNI answered 2019-10-07T00:39:53Z
translate from https://stackoverflow.com:/questions/276512/what-is-the-full-for-loop-syntax-in-c