C++:打破主循环

sun*_*tch 9 c++ loops break

我正在准备一些代码:

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555)
          break;
    }

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}
Run Code Online (Sandbox Code Playgroud)

我想int a通过break;在b循环(循环变量int b)中使用语句来打破主循环(循环变量).

我该怎么做?

Car*_*rum 34

用一个goto.

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555)
          goto loopDone;
    }

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}
loopDone:
Run Code Online (Sandbox Code Playgroud)

  • +1:这正是"goto"留在语言中的极端条件. (14认同)
  • 我正拿着一盒爆米花和一些苏打水,然后靠在椅子上观看即将到来的支持者与goto对手之间的火焰战! (9认同)
  • 做一点功能和回报.正如其他人在其他答案中所说:重构!复杂的代码不利于可读性和理解. (3认同)
  • @James Curran - +1,但是没有什么特别需要这样做的.其他语言支持这一点而不诉诸于gotos.C设计得很糟糕.例如,Ada允许循环命名,并且在Ada中等效于"break"允许您指定被破坏的循环的名称. (2认同)
  • @Carl Norum:在C++中有更好的机制.其中一个例外.你的答案对C来说没问题(对于C++来说不是很多) (2认同)

GMa*_*ckG 23

要么做四件事之一:使用goto,使用throw,使用旗帜或重构.

许多人不同意使用goto,但有时它是一个干净的解决方案.(大多数情况下,它不是,但它存在是有原因的.)但是,我发现使用goto权证是一个重构.

第二个解决方案是抛出一些特殊异常,然后在主循环之外捕获它.这是对例外制度的滥用,基本上更糟goto; 用一个goto而不是这个.

第三种解决方案是使用标志某种.这基本上是"更安全" goto,但有些人可能认为这有点丑陋.(特别是有多个级别.虽然在这种情况下你担心你的代码是多么丑陋.)

我建议的解决方案是重构.无论你做什么,都太过分了.您应该将内部循环移动到一个函数中,并调用该函数.返回主循环只是从该函数返回.(换句话说"我的工作已经完成.")


Jus*_*ier 20

我建议将代码重构为函数.然后你可以return从该函数而不是使用break:

void myFunc() 
{
    for(int a = 1; a <= 100; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000; b++)    //loop b
        {
           if(b == 1555) // Logic is just an example,
              return;    // since it will always return
        }

        .
        .
        .
    }
}
Run Code Online (Sandbox Code Playgroud)

这 - 或者甚至是更复杂的代码重构 - 应该能够提供一个干净,优雅的解决方案.或者,如果您只想快速修复,可以使用条件变量:

for(int a = 1; a <= 100; a++)    //loop a (main loop)
{
    bool cond = false;

    for(int b = 1000; b <= 2000; b++)    //loop b
    {
       if(b == 1555){
          cond = true;
          break;
       }
    }

    if (cond) break;

    .
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

其他人建议使用goto.虽然这是另一个快速解决方案,但我强烈建议不要这样做,特别是如果您在严格的环境中工作,其中代码将经过同行评审并在未来几年内使用.

我看来,这种goto方法比函数/返回重构更难维护,尤其是在其他人对代码进行更改时.此外,您必须证明goto团队中的任何其他人偶然会遇到代码.

  • @James:或者重构你讨厌的多级代码而不做任何事情. (14认同)
  • 这适用于两个级别,但不能很好地扩展.这就是你咬牙并使用`goto`的情况. (9认同)
  • 如果你正在编写多重嵌套循环,那么提取到函数是一个更加可读的替代`goto`. (4认同)
  • @GMan:同意.我的典型解决方案是将外部循环体放入子程序中,并使用"返回". (3认同)