如何在Objective-C中打破两个嵌套的for循环?

How can I break out of two nested for loops in Objective-C?

我有两个这样嵌套的for循环:

1
2
3
4
5
for(...) {
    for(...) {

    }
}

我知道有一个break声明。但是我很困惑,它是打破了两个循环,还是只打破了一个循环?我需要在我发现重复多次是没有意义的时候立即将这两个都打破。


如果使用goto简化代码,那么它是合适的。

1
2
3
4
5
6
7
8
9
10
11
12
for (;;)
{
    for (;;)
    {
        break; /* breaks inner loop */
    }
    for (;;)
    {
        goto outer; /* breaks outer loop */
    }
}
outer:;


中断从一个循环中断,但可以向外部循环添加一个检查,该检查在内部中断时中断。

1
2
3
4
5
6
7
8
9
bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
   for ( ... ) {
      if (...) {
         dobreak = true;
         break;
      }
   }
}


break语句只会使您脱离最内部的循环。如果您不希望在专用状态变量的代码、内存和性能方面增加额外开销,我建议将代码重构为它自己的函数或方法,并使用return退出所有循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void do_lots_of_work(void)
{
  int i, j;

  for(i=0; i<10 ; i++)
  {
    for(j=0;j< 10; j++)
    {
     ..
     ..
     if(disaster_struck())
      return; /* Gets us out of the loops, and the function too. */
    }
  }
}


除了前面提到的标志变量或goto之外,您还可以抛出一个objective-c异常:

1
2
3
4
5
6
7
8
9
10
@try {
  for() {
    for() {
       @throw ...
    }
  }
}
@catch{
  ...
}


其他人也提到了如何设置标志或使用goto,但我建议您重构代码,以便将内部循环转换为单独的方法。然后,该方法可以返回一些标志来指示外部循环应该是break。如果您恰当地命名您的方法,这将更易于阅读。

1
2
3
4
5
6
7
8
9
10
11
for (int i = 0; i < 10; i++) {
   if (timeToStop(i)) break;
}

-(bool) timeToStop: (int) i {
    for (int j = 0; j < 10; j++) {
        if (somethingBadHappens) return true;
    }

    return false;
}

伪代码,没有测试过,但你明白了。


另一种解决方案是将函数中的第二个循环分解为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int i;

for(i=0; i<10 ; i++){
    if !innerLoop(i) {
        break;
    }
}

bool innerLoop(int i)
    int j;
    for(j=0;j< 10; j++){
        doSomthing(i,j);
        if(endcondtion){
            return false;
        }
    }
}


休息前更换上环计数器

1
2
3
4
5
6
7
for(i=0; i<10 ; i++)
  for(j=0;j< 10; j++){
     ..
     ..
     i = 10;
     break;
  }


可能最简单的方法是使用"flag"变量

1
2
3
4
5
6
for(i=0; i<10 && (done==false); i++)
  for(j=0;j< 10; j++){
     ..
     ..
     if(...){done=true; break;}
  }


break语句将只中断作用域中的循环,即父循环。如果您还想脱离第二个循环,可以使用一个布尔变量,该变量在两个循环的范围内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bool isTerminated = false;

for (...)
{
    if (!isTerminated)
    {
        for(...)
        {
            ...

            isTerminated = true;
            break;
        }
    }
    else
    {
        break;
    }
}

break语句从最里面的循环中断。需要一个额外的测试和中断语句来中断外部循环。


对于GRINS来说,将这个对/错检查改为一个方法,并使用return语句如何:

1
2
3
4
5
6
7
8
9
10
11
12
13
- (bool) checkTrueFalse: parameters{

   for ( ...) {
      for ( ... ) {

         if (...) {
            return true;
         }

      }
   }
   return false;
}


与上一个完全一样,通常如下:

1
2
3
4
5
6
7
8
for(i=0;i<a;i++){  
 for(j=0;j<a;j++){
  if(Something_goes_wrong){
   i=a;
   break;
   }
 }
}

如果在一组嵌套循环中执行一个中断,则只终止执行中断的最内层循环。(就像标准C)