我已经看到了一些非常奇怪 for 循环的时候读的其他人的代码。我已经试图寻找一种完整的语法解释 for 循环在 C 但它是非常困难的,因为单词"for"现在不相关的句子,使得几乎不可能搜索到了谷歌有效。

这个问题来到我的脑海之后读取 这个线程 这让我好奇了。

for 在这里:

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

在中间状况有一个逗号分开的两条码,这是什么逗号做的吗?逗号在右边我的理解,因为它使这两个 a>>=1b<<=1.

但是,在一个循环中退出条件,会发生什么?它不会退出的时候 p==0, 时 a==1 或两者时发生的?

这将是巨大的,如果任何人能帮我了解这个也许我指的方向的一个完整的 for 环语法的描述。

有帮助吗?

解决方案

逗号不是唯一的循环;这是逗号操作员。

x = (a, b);

会做的第一a、b、然后设x的值b。

在语法是:

for (init; condition; increment)
    ...

其中有些(忽略 continuebreak 现在)相当于:

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

所以你的循环的例子是(再次忽视了 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;
}

两个额外细节的循环,它们不在简化转换到一个循环:

  • 如果条件是省略,它是总是 true (导致一个无限的循环,除非一个 break, goto, 或其他东西打破的循环)。
  • 一个 continue 行为如同它是转到一个标签之前增加,与不同的一个 continue 在同时循环,这将跳过增加。

此外,一个重要的细节约的逗号操作员:它是一个顺序点像 &&|| (这就是为什么我可以分为单独的语句,并保持其意义不变).


变化C99

C99标准引入了几个细微差别没有提到早些时候在这的解释(这是非常好的C89/C90).

第一,所有循环块在他们自己的权利。有效,

for (...) { ... }

是自己包裹在一双牙套

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

该标准说:

ISO/IEC9899:1999年§6.8.5迭代的声明

¶5个迭代的声明是一个方框,其范围是一个严格的子集的范围 封闭区块。循环体也是一个方框,其范围是一个严格的子集的范围 迭代发言。

这也是中所述的理由在条款的额外设置的括号。

其次, init 部在C99可以是(一)《宣言》,作为在

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

现在的'块包裹的循环进入其自己;这解释了为什么变 i 无法访问以外的循环。你可以宣布的多个变量,但他们必须全部同一类型:

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

该标准说:

ISO/IEC9899:1999年§6.8.5.3的声明

该声明

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

行为如下:表表达-2的控制表达这是 之前评估每一执行的循环机构。表表达-3 评估为无效的表达之后,每一个执行的循环机构。如果条款-1是 《宣言》的保护范围的任何变量,它宣布为剩余的宣言和 整个循环,包括其他两种表达式;它达到了执行 之前的第一个评估控制的表达。如果条款-1是一种表达,这是 评估为无效的表达之前首先评估的控制表达。133)

这两个条款-1和表3中可以省略。一省略表达-2替换 非零恒定。

133) 因此,条款-1指定的初始化的循环,可能宣布一个或多个变量使用在 的循环;控制的表达,表达-2,指定一个评价之前作出的每一次迭代, 这样,执行的循环的继续,直到表达比较等于0;和表达-3 指定的操作(例如递增),之后执行的每一次迭代。

其他提示

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

循环的

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

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

C式循环的由三个表达方式:

for (initializer; condition; counter) statement_or_statement_block;
  • 初始化器运行一次,当时的循环的开始。
  • 条件是检查之前的每一次迭代。循环的运行,长则将其认定为真实的。
  • 计数器运行一次后每次迭代。

这些零件的每一个可以表达有效的语言编写的循环。这意味着他们可以使用更多的创造性。任何你想要做的事先可以进入初始化程序,任何你想要做的之间可以进入的状况或反,一直到这里的循环已经有身体了。

为了实现这一目标,逗号操作者有很方便的。它可以让你链表达在一起,形成一个单一的新的表达。大部分时间是用这种方式在一个循环,其他影响的逗号操作员(例如值分配的考虑因素)发挥次要的作用。

即使可以做聪明的事情,通过使用的语法创造性地-我能留下它直到我找到一个 真的 很好的理由这样做。播放的代码的高尔夫用的循环使得码更难于阅读和理解(以及维护).

维基百科有一个很好的 文章在环路 为好。

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

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

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

当我在“条件”中进行两次测试时,Gnu编译器会发出此警告。 for循环的部分

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top