C ++:打破主循环

时间:2010-08-09 17:11:36

标签: 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
    {
       .
       .
       .
    }
}

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

我该怎么做?

11 个答案:

答案 0 :(得分: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:

答案 1 :(得分:23)

要么执行以下四项操作之一:使用goto,使用throw,使用标记或重构。

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

第二个解决方案是to throw一些特殊异常,然后在主循环之外捕获它。这是对例外系统的滥用,基本上更糟糕goto;使用goto代替此。

第三种解决方案是使用a flagsome sort。这基本上是一个“更安全”goto,但有些人可能认为这有点丑陋。 (特别是有多个级别。虽然在这种情况下你关心的是你的代码是多么丑陋。)

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

答案 2 :(得分: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
        }

        .
        .
        .
    }
}

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

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;

    .
    .
    .
}

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

我的观点中,goto方法比函数/返回重构更难维护,尤其是在其他人对代码进行更改时。此外,您必须向团队中其他任何偶然发现代码的人goto证明其合理性。

答案 3 :(得分:4)

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

    for(int c = 2001; c <= 3000; c++)    //loop c
    {
       .
       .
       .
    }
}
end:

答案 4 :(得分:4)

一次退出两个此类循环的唯一方法是gotothrowreturnthrowreturn可能不合适(特别是throw,如果条件不是例外)。或者,您可以设置某种条件(bool breakout;),并且如果它是真的则继续打破。

答案 5 :(得分:4)

如果合适,你可以创建一个函数,其内容是一个循环,并使用return。

public void bigLoop()
{
    for(int a = 1; a <= 100; a++)
    {
        for(int b = 1000; b <= 2000; b++)
        {
            if(b == 1555)
                return;
        }

        for(int c = 2001; c <= 3000; c++)
        {
            .
            .
            .
        }
    }
}//bigLoop

答案 6 :(得分:4)

\(◕◡◕)/

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

        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
}();

答案 7 :(得分:3)

  1. 使用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 done;
        }
        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
    done:
    
  2. 设置每个循环测试的标记值:

    bool sentinel = true ;
    for(int a = 1; a <= 100 && sentinel ; a++)    //loop a (main loop)
    {
        for(int b = 1000; b <= 2000 && sentinel; b++)    //loop b
        {
           if(b == 1555)
              sentinel = false;
        }
        for(int c = 2001; c <= 3000 && sentinel; c++)    //loop c
        {
           .
           .
           .
        }
    }
    

答案 8 :(得分:2)

一个简单的策略是将循环放在一个单独的函数中并在选定的点进行返回:

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

        for(int c = 2001; c <= 3000; c++)    //loop c
        {
           .
           .
           .
        }
    }
}

也可以返回任何类型的结果,返回值或函数的参考参数。

答案 9 :(得分:2)

理想的方法是重新分解代码,以便不再需要这种复杂的嵌套循环结构。根据代码的其余部分,bc循环可能成为单个函数的候选者,如果不是整个a循环。

因为看起来循环bc遍历相邻范围,为什么不组合它们并减少循环嵌套?

for (int a = 1; a <= 100; a++)    //loop a (main loop)
{
    int count = 1000;
    while (count <= 3000) // combined loops 'b' and 'c'
    {
        if (count <= 2000)
        {
            // Old loop 'b' code
            if (b == 1555)
                goto fullbreak;
        }
        else
        {
            // Old loop 'c' code
            ...
        }
        count++;
    }
}
fullbreak:

您还可以使用条件变量而不是goto。如果您想要摆脱旧的b循环但仍处理旧的c循环,只需在旧的count = 2001循环代码中设置b

理想情况下,您至少可以将其重新计算为更像

的内容
for (int a = 1; a <= 100; a++)    //loop a (main loop)
{
    if (process_inner_loop(pass, required, args))
        break;
}

其中函数process_inner_loop包装原始的两个循环,如果要打破封闭循环,则返回非零值。现在,您可以简单goto

,而不是使用return 1;或条件变量

答案 10 :(得分:1)

使用这种模式

for(int a = 1; a <= 100; a++)
{
    int breakMain = 0;
    for(int b = 1000; b <= 2000; b++)
    {
       if(b == 1555)
       {
           breakMain = 1;
           break;
       }
    }

    if(breakMain)
         break;

    for(int c = 2001; c <= 3000; c++)
    {
       .
       .
       .
    }
}