C 一次打破许多for循环的好方法是什么?

C 一次打破许多for循环的好方法是什么?,c,for-loop,break,C,For Loop,Break,假设我需要在最内层的循环中发生某个事件时,同时中断三个或四个嵌套的for循环做这件事的好方法是什么? 我要做的是像这样使用标志: int i, j, k; int flag1 = 0; int flag2 = 0; for (i = 0; i < 100; i++) { for (j = 0; j < 100; j++) { for (k = 0; k < 100; k++) { if (k == 50) {

假设我需要在最内层的循环中发生某个事件时,同时中断三个或四个嵌套的for循环做这件事的好方法是什么?

我要做的是像这样使用标志:

int i, j, k;
int flag1 = 0;
int flag2 = 0;

for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                flag1 = 1;
                flag2 = 1;
                break;
            }
        }
        if (flag1 == 1)break;
    }
    if (flag2 == 1)break;
}
for (i = 0; i < 100 && !flag2; i++) {
for (j = 0; j < 100 && !flag1; j++) {
    for (k = 0; k < 100; k++) {
        if (k == 50) {
            k = 100;
            i = 100;
            j = 100;
        }
    }
}
inti,j,k;
int flag1=0;
int flag2=0;
对于(i=0;i<100;i++){
对于(j=0;j<100;j++){
对于(k=0;k<100;k++){
如果(k==50){
flag1=1;
flag2=1;
打破
}
}
如果(flag1==1)中断;
}
如果(flag2==1)中断;
}
我不认为这是特别整洁的


如何完成相同的任务?(不使用跳转)

如果使用Java,可以将标签与每个for块关联,然后在continue语句后引用标签。例如:

outerfor:
for (int i=0; i<5; i++) {
    innerfor:
    for (int j=0; j<5; j++) {
        if (i == 1 && j == 2) {
             continue outerfor;
        }
    }
}
outerfor:
对于(inti=0;i来说,只是稍微好一点

int i, j, k;
int flag1 = 0;
int flag2 = 0;

for (i = 0; i < 100 && !flag2; i++) {
    for (j = 0; j < 100 && !flag1; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                flag1 = 1;
                flag2 = 1;
                break;
            }
        }
    }
}
inti,j,k;
int flag1=0;
int flag2=0;
对于(i=0;i<100&&!flag2;i++){
对于(j=0;j<100&&!flag1;j++){
对于(k=0;k<100;k++){
如果(k==50){
flag1=1;
flag2=1;
打破
}
}
}
}

但是,如果你真的需要这些循环,那么在每个循环中明确声明它必须满足哪些条件才能继续,以确保可读性是有意义的。

使用goto。它简洁明了。

将所有循环放在一个函数中,只返回而不是中断

您将如何完成相同的任务?(不使用跳转)

为什么?没有什么是万恶的,每一种工具都有它的用途(除了
gets()
)。在这里使用
goto
可以让你的代码看起来更干净,并且是我们唯一的选择之一(假设为C)。看:

inti,j,k;
对于(i=0;i<100;i++){
对于(j=0;j<100;j++){
对于(k=0;k<100;k++){
如果(k==50){
转到终点;
}
}
}
}
完:

比所有这些标志变量更清晰,它甚至可以更清楚地显示代码在做什么。

有时您可以使用如下技巧:

int i, j, k;
int flag1 = 0;
int flag2 = 0;

for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                flag1 = 1;
                flag2 = 1;
                break;
            }
        }
        if (flag1 == 1)break;
    }
    if (flag2 == 1)break;
}
for (i = 0; i < 100 && !flag2; i++) {
for (j = 0; j < 100 && !flag1; j++) {
    for (k = 0; k < 100; k++) {
        if (k == 50) {
            k = 100;
            i = 100;
            j = 100;
        }
    }
}
for(i=0;i<100&&!flag2;i++){
对于(j=0;j<100&&!flag1;j++){
对于(k=0;k<100;k++){
如果(k==50){
k=100;
i=100;
j=100;
}
}
}
}

或在循环中声明添加标志:

bool end = false;
for(int i =0; i < 1000 && !end; i++) {
   //do thing
   end = true;
}
bool end=false;
对于(int i=0;i<1000&&!end;i++){
//做事
结束=真;
}
我想这只需要一条线,但是很干净


贾斯汀

一种方法是使用状态机。但我仍然使用goto。它更简单。:)

state=0;
而(状态>=0){
开关(状态){
案例0:i=0;状态=1;//对于i=0
案例1:
i++;
if(i<100)//if for i<100未完成
state=2;//执行内部j循环
其他的
state=-1;//完成循环
案例2:j=0;state=3;//对于j=0
案例3:
j++;
if(j<100)//如果j<100未完成
state=4//执行内部k循环
其他的
state=1;//返回到循环i
打破
案例4:k=0;状态=5;
案例5:
k++;
如果(k==50){
状态=-1;
打破
}
if(k<100)//如果k循环未完成
state=5;//执行此循环
其他的
state=3;//返回上循环
打破
默认值:state=-1;
}
}

转到
。这是为数不多的几个地方之一,
goto
是合适的工具,并且通常是为什么
goto
不是完全邪恶的论点

但有时我会这样做:

void foo() {
    bar_t *b = make_bar();
    foo_helper(bar);
    free_bar(b);
}

void foo_helper(bar_t *b) {
    int i,j;
    for (i=0; i < imax; i++) {
        for (j=0; j < jmax; j++) {
            if (uhoh(i, j) {
                return;
            }
        }
    }
}
void foo(){
bar_t*b=制造_bar();
福乌助手(酒吧);
免费酒吧(b);
}
void foo_helper(bar_t*b){
int i,j;
对于(i=0;i

我的想法是,我得到了一个保证的免费酒吧,加上我得到了一个干净的两级中断开关通过返回。

除以0是我知道的最可靠的方法,将打破任何数量的循环。这是工作的,因为DIV汇编指令不喜欢这种愚蠢

因此,您可以尝试以下方法:

int i, j, k;
int flag1 = 0;
int flag2 = 0;

for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                flag1 = 1;
                flag2 = 1;
                int z = 1 / 0;  // we're outta here!!!
            }
        }
        if (flag1 == 1)break;
    }
    if (flag2 == 1)break;
}
inti,j,k;
int flag1=0;
int flag2=0;
对于(i=0;i<100;i++){
对于(j=0;j<100;j++){
对于(k=0;k<100;k++){
如果(k==50){
flag1=1;
flag2=1;
int z=1/0;//我们离开这里!!!
}
}
如果(flag1==1)中断;
}
如果(flag2==1)中断;
}

从发生在此类事件上的
陷阱中返回给读者作为练习(这很简单)。

如果过早完成任何循环总是意味着你也必须打破封闭循环,那么你不需要任何额外的标志。整个过程可能如下所示

int i, j, k;
for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50)
                break;
        }
        if (k < 100) break;
    }
    if (j < 100) break;
}
inti,j,k;
对于(i=0;i<100;i++){
对于(j=0;j<100;j++){
对于(k=0;k<100;k++){
如果(k==50)
打破
}
如果(k<100)断裂;
}
如果(j<100)断裂;
}

根据我的经验,这是大多数情况下所需要的。

一点愚蠢的自我记录:

int i, j, k;
int done = 0;

for (i = 0; i < 100 && ! done; i++) {
    for (j = 0; j < 100 && ! done; j++) {
        for (k = 0; k < 100 && ! done; k++) {
            if (k == 50) we_are(done);
        }
    }
}

//...

void we_are(int *done) {
    *done = 1;
}
inti,j,k;
int done=0;
对于(i=0;i<100&&!完成;i++){
对于(j=0;j<100&&!完成;j++){
对于(k=0;k<100&&!完成;k++){
如果(k==50),我们就完成了;
}
}
}
//...
我们是空的(int*done){
*完成=1;
}
<>但是,你不应该有三个嵌套for循环。你应该考虑重构成D。
  int i, j, k;

  for (i = 0; i < 100; i++) {
      for (j = 0; j < 100; j++) {
          for (k = 0; k < 100; k++) {
              if (k == 50) {
                  return;
              }
          }
      }
  }
int i, j, k;

for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                i = j = k = INT_MAX;
                break;
            }
        }
    }
}
int i, j, k;

for (i = 0; i < 100; i++) {
    for (j = 0; j < 100; j++) {
        for (k = 0; k < 100; k++) {
            if (k == 50) {
                break(3);
            }
        }
    }
}