【问题标题】:How to convert this for loop to a while loop in C using a continue statement如何使用 continue 语句将此 for 循环转换为 C 中的 while 循环
【发布时间】:2017-08-31 00:45:35
【问题描述】:

我正在尝试转换以下 for 循环

for( x = 1; x <= 10; x++ ){

    if( x == 5 ){
        continue;
    }

    printf("%d ", x);

}

进入一个while循环。但是,以下对我来说似乎合理的代码没有正确执行:

int x = 1;
while( x <= 10 ){
    if( x == 5){
       continue;
    }
    printf("%d ", x);
    x++;
}

为什么会这样?

提前致谢。

【问题讨论】:

  • 你确定你的 for 循环是正确的吗?最后的x++; 在我看来非常可疑
  • @carcigenicate,这只是我的一个错字。我现在已经修好了。在原文中,我有 if 语句。谢谢。
  • 你的 for 循环每次迭代都会增加 x 两次,而你的 while 循环不会。
  • @Amadeus 感谢您指出这一点。这也是一个错字。
  • 你的 while 循环永远不会结束。当 x == 5 你永远继续,因为你永远不会增加它。 ideone.com/B2eLwo

标签: c for-loop while-loop


【解决方案1】:

这是 JavaScript 中 for 循环的一个版本,因此我们可以在此处运行它并查看输出。 C 和 JavaScript 具有相同的循环语义,因此这是测试代码的便捷方式:

for( x = 1; x <= 10; x++ ) {

    if( x == 5 ) {
        continue;
    }

    console.log( x );
}

现在,为什么您的 while 循环不产生此输出?这是因为continue 声明。这是您的 while 循环的 JavaScript 版本:

var x = 1;
while( x <= 10 ) {

    if( x == 5) {
       continue;
    }

    console.log( x );

    x++;
}

再三考虑,不要运行它!事实上,我去掉了snippet 标签,所以你不要运行它。因为这就是问题所在……

当您在任何类型的循环中使用continue 时,它会跳过循环体 的其余部分。在for 循环中,x++ 不是循环体的一部分。它是for 语句本身的一部分,因此即使您在循环中使用continue,它也会运行。在while 循环中,x++ 是循环体的一部分,因此它与循环体的其余部分一起被跳过。

x5 时,您的while 版本将陷入无限循环,因为在循环迭代期间它不会增加x,实际上永远不会再增加x

现在提供一些建议:编写while 循环当然是可能,它的工作原理类似于更正后的for 循环,但它会更复杂一些。为什么要使用while 而不是for?为简单起见,坚持使用for 循环,或解释您想改用while 的原因。

一般来说,可以说下面的for循环和while循环是等价的:

for( a; b; c ) {
    // loop body
}

a;
while( b ) {
    // loop body
    c;
}

但是当你在循环体中使用continue时,它们就不一样了,原因如上所述。

如果您真的想使用 while,可以使用 goto,如 Amadeus 的回答中所示。或者您可以重新排列循环体,如下所示:

var x = 1;
while( x <= 10 ) {

    if( x != 5) {
        console.log( x );
    }

    x++;
}

【讨论】:

  • 感谢您的回复!是的,for 循环中的额外增量是一个意外。至于我为什么要尝试使用while循环来执行此任务,我只是在学习C时摆弄。
【解决方案2】:

一个 for 循环可以看作是:

for (initialization; test; increment) 
{
    body
}

并且可以使用保持这种格式的while循环来实现:

initialization;
while (test)
{
    body
    increment;
}

因此,在您的情况下,解决方案是(您正在使用 continue 语句,这意味着您必须跳过正文的其余部分并直接进入增量部分):

x = 1;
while (x <= 10) {
    if( x == 5 ){
        goto cont;
    }

    printf("%d ", x);

    cont: x++; // this increment is due the increment in for statement
}

使用goto跳转跳过body进入增量部分

【讨论】:

  • x==5的时候不是死循环吗?
  • 诀窍是当body 包含continuebreak。所以不太像initialization; while (test) { body increment; }
  • 您可以使用 else 来代替 goto。
【解决方案3】:

欢迎来到 C!如果您可以在不影响效率和可读性的情况下保持简单,那就这样做_(^.^)_/!即

int x = 1;
while( x <= 10 ){
    if( x != 5)
        printf("%d ", x);
    x++;
}

注意:如果您正在执行单个命令(在“if”语句中),您甚至不需要括号。

当您在一段时间内使用“继续”时,您跳过了循环的指令,您需要它们来进行迭代! ;)

【讨论】:

  • 虽然您不需要像您说明的那样在单个语句中需要大括号,但我们中的许多人不允许在我们的代码中省略它们。原因是它很容易出现像臭名昭著的 goto fail; 这样几年前导致安全漏洞的错误。如果您总是使用牙套,那么您就不太可能出现类似的问题。
  • 你能提供一些文章来解释/定义这种类型的安全漏洞吗,迈克尔?听起来很有趣!
  • 点击“goto fail;”我之前的评论中的文字,以获取有关该主题的出色文章。 (当像这样的格式化代码也是一个可点击的链接时,我希望 SO 更清楚;很难从它们的显示方式中分辨出来。)还可以在网络上搜索其他几篇文章的“goto fail”。还有一个方便的提示:如果您使用 Chrome 地址栏进行以“goto”或“google”等关键字开头的搜索,请在开头输入一个空格,以防止 Chrome 将其解释为关键字。
  • 非常感谢,迈克尔!欣赏!
【解决方案4】:

每次迭代(X==5 除外)都有两次迭代,一次在 for() 中,一次在正文中。试试这样的:

int x = 1;
while( x <= 10 ){
    if( x == 5){
      ;
    }else{
        printf("%d ", x);
        x++;
    }
    x++ // "for()" increment
}

【讨论】:

  • 又名if(x!=5)
【解决方案5】:

在第二个代码块中

int x = 1;
while( x <= 10 ){
    for( x == 5){
       continue;
    }
    printf("%d ", x);
    x++;
}

while 语句的第二行,你有for(x == 5) 而不是if (x == 5),就像你在第一个块的for循环中一样。

否则,这是将for循环写成while循环的正确方法,本质上是将初始化变量移到循环之外,并将修改语句放在最后。根据情况,一个可能比另一个更好,但它们是可以互换的。

编辑:

最好通过排除一次值为 5 的时间来最小化代码,而不是在不是时使用 continue。此外,另一张海报是正确的,您的 continue 语句将排除 x 的增量导致无限循环。

int x = 1;
while( x <= 10 ){
    if ( x != 5){
       printf("%d ", x);
    }
    x++;
}

【讨论】:

  • 感谢您的回复。事实上,“for”是一个错字,我的意思是它是一个 if,就像在原始代码中一样,但它不起作用。我没有得到我应该使用 while 循环 1 2 3 4 6 7 8 9 10 的输出。
【解决方案6】:

您只需要添加“else” - 如果“if 语句”不起作用,您想要做什么,或者您可以告诉程序在其他情况下要做什么:

int x = 1;
while( x <= 10 ){
    if( x != 5)
       printf("%d ", x);
    x++;
}

【讨论】:

  • 到达continue 后,您仍然没有到达x++。该代码的缺陷方式与 OP 相同。
猜你喜欢
  • 2015-12-13
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多