Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么是';继续';语句忽略';而';循环,但不在';对于';环_C_Loops_For Loop_While Loop_Continue - Fatal编程技术网

C 为什么是';继续';语句忽略';而';循环,但不在';对于';环

C 为什么是';继续';语句忽略';而';循环,但不在';对于';环,c,loops,for-loop,while-loop,continue,C,Loops,For Loop,While Loop,Continue,如果我在while循环中使用continue,但在for循环中运行良好,为什么它会进入无限循环? 循环计数器增量i++在中被忽略,而循环中,如果我在continue之后使用它,它将被忽略,但如果它在for循环中,它将起作用 如果continue忽略后续语句,那么它为什么不忽略for循环的第三条语句,其中包含计数器增量i++?鉴于for循环的第三条语句是在循环体之后执行的,因此for循环的第三条语句不也是继continue之后的第三条语句吗 while(i<10) //causes in

如果我在
while
循环中使用
continue
,但在
for
循环中运行良好,为什么它会进入无限循环?
循环计数器增量
i++
中被忽略,而
循环中,如果我在
continue
之后使用它,它将被忽略,但如果它在
for
循环中,它将起作用

如果
continue
忽略后续语句,那么它为什么不忽略
for
循环的
第三条语句,其中包含计数器增量
i++
?鉴于
for
循环的第三条语句是在循环体之后执行的,因此
for
循环的第三条语句不也是继
continue
之后的第三条语句吗

while(i<10)   //causes infinite loop
{
    ...
    continue
    i++
    ...
}

for(i=0;i<10;i++)  //works fine and exits after 10 iterations
{
    ...
    continue
    ...
}

while(i因为for的第三部分总是被执行。

您的
i
增量是在continue之后,所以它永远不会被执行

while(i<10)   //causes infinite loop
{
.........
continue
i++
......
}

while(i在任何循环中,continue将执行移回循环的顶部,在continue语句之后不执行任何其他指令


在这种情况下,始终执行for循环的定义(根据标准C),而i++;语句不会执行,因为它位于continue语句之后。

因为
continue
返回循环的开头。对于
for
,post操作
i++
是循环控件的一个组成部分,在循环体重新启动之前执行


使用
while
i++
只是循环体中的另一个语句(与
a=b
没有什么不同),如果在到达它之前
continue
,则跳过。

原因是
continue
语句将使循环体中紧跟其后的语句短路。由于编写
while
循环时,在
continue
语句之后有increment语句,因此它会短路。您可以n通过更改
while
循环来解决此问题

许多教科书声称:

for (i = 0; i < N; ++i) {
    /*...*/
}
(i=0;i{ /*...*/ }
相当于:

i = 0;
while (i < N) {
    /*...*/
    ++i;
}
i=0;
而(i
但事实上,这就像:

j = 0;
while ((i = j++) < N) {
    /*...*/
}
j=0;
而((i=j++)
或者,更迂腐一点:

i = 0;
if (i < 10) do {
    /*...*/
} while (++i, (i < 10));
i=0;
如果(i<10)do{
/*...*/
}而(++i,(i<10));

这两种方法更为等效,因为现在如果
的主体在
时有一个
continue
,那么增量仍然会出现,就像在
for
中一样。后者仅在迭代完成后执行增量,就像
for
(前者在迭代之前执行增量,将其保存在
i
中,直到迭代之后).

continue
语句将控件跳到循环当前迭代中语句的末尾,即跳过当前迭代中语句的执行,并移动到循环的下一个迭代

使用
while
loop,
continue
语句使控制到达语句的末尾(包括increment语句),从而使循环永远继续


使用
for
循环,
continue
语句将控件跳到语句末尾并执行增量语句(在
for
循环中,增量语句被视为与写在循环体中的语句分离).

for循环保存条件语句和增量,因此当条件满足时,它将执行for循环中的语句,但如果写入continue语句,它将再次到达for循环的第一行,即条件语句的增量和检查,如果满足,则再次进入执行。 对于while循环,它只检查条件语句,如果条件满足,则执行while循环中的语句。
所以continue不会在它之后执行任何一行。因此,您的条件每次都满足,并进入无限循环。

continue
绕过块的其余部分,如果满足循环的条件,则从块的顶部重新开始

下一个问题是:“那我该怎么办?” 我能想到两个答案

例如:

解决方案#1:手动递增

void foo ()
{
    size_t i = 0;
    do
    {
        /*...*/
        if ( /*...*/ )
        {
            /*...*/
            i++;
            continue;
        }
        /*...*/
        i++;
    } while ( /* loop conditional */ );
}
解决方案2:唯一有效的
goto
*

void foo ()
{
    size_t i = 0;
    do
    {
        /*...*/
        if ( /*...*/ )
        {
            /*...*/
            goto foo_next;
        }
        /*...*/
foo_next:
        i++;
    } while ( /* loop conditional */ );
}
goto
在这种情况下是有效的,因为两个位置的增量在技术上是相同的指令。当每次迭代的可变变量更复杂时,此解决方案尤其相关;例如,设置多个变量或使用方程或函数修改值

对于单个递增或递减语句,解决方案#1可能是有利的;但是,应该注意的是:如果在这样的实现之后修改了代码,那么必须记住更新语句的两个实例(这可能容易出现错误,特别是如果修改在一段较长的时间之后发生**)。因此,我高度推荐解决方案#2

*考虑使用和使用<代码> Goto 不好的练习。我建议你自己决定,留给你这个:

**提醒这一必要性的注释可能就足够了,但是——如果遵循了我的建议——中的每次迭代可变变量仅限于一条语句。我引用:

从来没有理由评论一行


-Linus Torvalds(source:)

看看输出程序集,你会发现for循环并不是按照你的想法展开的。Q:如果你在while循环中
i++
之后加上
continue,会发生什么?Q:你知道初始化、增量和条件都是同一个构造的一部分
void foo ()
{
    size_t i = 0;
    do
    {
        /*...*/
        if ( /*...*/ )
        {
            /*...*/
            goto foo_next;
        }
        /*...*/
foo_next:
        i++;
    } while ( /* loop conditional */ );
}