如果我使用break
语句,它只会破坏内部循环,我需要使用一些标志来打破外部循环。但是如果有很多嵌套循环,那么代码看起来不会很好。
还有其他方法可以打破所有循环吗? (请不要使用goto stmt
。)
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; j++) {
if(condition) {
// both of the loops need to break and control will go to stmt2
}
}
}
stmt2
答案 0 :(得分:151)
不,不要破坏break
的乐趣。这是goto
;)
如果不是这样,那么你可以使用标志来打破深嵌套循环。
打破嵌套循环的另一种方法是将两个循环分解为单独的函数,并在想要退出时从该函数返回。
总结 - 打破嵌套循环:
goto
无法抗拒包含xkcd:)
Goto's are considered harmful但是评论中的许多人都认为不一定是这样。如果明智地使用它可以是一个很好的工具。适度使用的任何东西都很有趣。
答案 1 :(得分:40)
怎么样:
if(condition) {
i = j = 1000;break;
}
答案 2 :(得分:34)
bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
for (int j = 0; (j < 1000) && !stop; j++)
{
if (condition)
stop = true;
}
}
答案 3 :(得分:23)
一种方法是将所有嵌套循环放入一个函数中,并从最内层循环返回,需要打破所有循环。
function()
{
for(int i=0; i<1000; i++)
{
for(int j=0; j<1000;j++)
{
if (condition)
return;
}
}
}
答案 4 :(得分:15)
我认为goto
将解决问题
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
goto end;
}
}
}
end:
stmt2
答案 5 :(得分:11)
如果你想要它可读,你需要一个布尔变量:
bool broke = false;
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
broke = true;
break;
}
}
if (broke)
break;
}
如果您希望它具有较低的可读性,您可以加入布尔评估:
bool broke = false;
for(int i = 0; i < 1000 && !broke; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
broke = true;
break;
}
}
}
作为一种终极方式,您可以使初始循环无效:
for(int i = 0; i < size; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
i = size;
break;
}
}
}
答案 6 :(得分:7)
使用来自LLVM团队的明智建议:
“将谓词循环转换为谓词函数”
见:
http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions
答案 7 :(得分:4)
如果你需要i和j的值,这应该有效 但性能低于其他人
for(i;i< 1000; i++){
for(j; j< 1000; j++){
if(condition)
break;
}
if(condition) //the same condition
break;
}
答案 8 :(得分:3)
警告:这个答案显示了一个真正模糊的结构。
如果您使用的是GCC,请查看this library。
与在PHP中一样,break
可以接受要退出的嵌套循环的数量。
你可以这样写:
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; j++) {
if(condition) {
// break two nested enclosing loops
break(2);
}
}
}
答案 9 :(得分:2)
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if(condition) {
goto end;
}
}
end:
答案 10 :(得分:1)
我注意到问题很简单,“还有其他方法可以打破所有循环吗?”我看不到任何限定,但不是goto
,特别是OP并没有要求采用 good 方式。那么,我们如何longjmp
走出内循环呢? :-)
#include <stdio.h>
#include <setjmp.h>
int main(int argc, char* argv[]) {
int counter = 0;
jmp_buf look_ma_no_goto;
if (!setjmp(look_ma_no_goto)) {
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 1000; j++) {
if (i == 500 && j == 500) {
longjmp(look_ma_no_goto, 1);
}
counter++;
}
}
}
printf("counter=%d\n", counter);
}
setjmp
函数返回两次。第一次,它返回0,程序执行嵌套的for循环。然后,当i
和j
都为500时,它将执行longjmp
,这将导致setjmp
再次返回值1,从而跳过循环。
longjmp
不仅可以使您摆脱嵌套循环,还可以与嵌套函数一起使用!
答案 11 :(得分:0)
另一种方法是将代码从两个for循环重构为一个for循环和一个手动循环。这样,手动循环中的中断适用于外部循环。我在Gauss-Jordan Elimination中用过一次,它需要三个嵌套循环才能处理。
for (int i = 0; i < 1000; i++)
{
int j = 0;
MANUAL_LOOP:;
if (j < 1000)
{
if (condition)
{
break;
}
j++;
goto MANUAL_LOOP;
}
}
答案 12 :(得分:-1)
int i = 0, j= 0;
for(i;i< 1000; i++){
for(j; j< 1000; j++){
if(condition){
i = j = 1001;
break;
}
}
}
将打破两个循环。
答案 13 :(得分:-1)
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if(condition) {
func(para1, para2...);
return;
}
}
}
func(para1, para2...) {
stmt2;
}
答案 14 :(得分:-2)
i = 0;
do
{
for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here!
{
if (condition)
{
break;
}
}
++i;
} while ((i < 1000) && !condition);