我正准备一些代码:
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
)。
我该怎么做?
答案 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 flag的some 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)
一次退出两个此类循环的唯一方法是goto
或throw
或return
,throw
和return
可能不合适(特别是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)
使用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:
设置每个循环测试的标记值:
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)
理想的方法是重新分解代码,以便不再需要这种复杂的嵌套循环结构。根据代码的其余部分,b
和c
循环可能成为单个函数的候选者,如果不是整个a
循环。
因为看起来循环b
和c
遍历相邻范围,为什么不组合它们并减少循环嵌套?
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++)
{
.
.
.
}
}