Как я могу вырваться из двух вложенных циклов for в Objective-C?



у меня есть два цикла для вложенных, как это:



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

}
}


Я знаю, что есть break заявление. Но я смущен, если он ломает оба цикла или только тот, в котором он был вызван? Мне нужно сломать оба, как только я вижу, что нет смысла повторять больше раз.

767   13  

13 ответов:

break выходит из одного цикла, но вы можете добавить проверку к внешнему циклу, который ломается, когда внутренний разрывается.

bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
   for ( ... ) {
      if (...) {
         dobreak = true;
         break;
      }
   }
}

Если использование goto упрощает код, то это было бы уместно.

for (;;) 
{
    for (;;) 
    {
        break; /* breaks inner loop */
    } 
    for (;;) 
    {
        goto outer; /* breaks outer loop */
    }
} 
outer:;

The break оператор только выводит вас из самого внутреннего цикла. Если вы не хотите, чтобы добавленные накладные расходы в коде, памяти и производительности выделенной переменной состояния, я рекомендую рефакторинг кода в функцию или метод самостоятельно и с помощью return выйти из всех циклов:

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:

@try {
  for() {
    for() {
       @throw ...
    }
  }
}
@catch{
  ...
}

другие упомянули, как вы можете установить флаг или использовать goto, но я бы рекомендовал рефакторинг вашего кода так, чтобы внутренний цикл превратился в отдельный метод. Затем этот метод может вернуть некоторый флаг, чтобы указать, что внешний цикл должен break. Если вы назовете свои методы соответствующим образом, это будет гораздо более читаемым.

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;
}

псевдокод, не проверено, но вы поняли идею.

оператор break выйдет только из цикла в области видимости, который является родительским циклом. Если вы хотите вырваться из второго цикла, вы можете использовать булеву переменную, которая находится в области обоих циклов

bool isTerminated = false;

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

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

изменить счетчик верхнего цикла перед перерывом

for(i=0; i<10 ; i++)
  for(j=0;j< 10; j++){
     ..
     ..
     i = 10; 
     break;
  }

вероятно, самый простой способ-использовать переменную "флаг"

for(i=0; i<10 && (done==false); i++)
  for(j=0;j< 10; j++){
     ..
     ..
     if(...){done=true; break;}
  }

другое решение состоит в том, чтобы разложить второй цикл в функции:

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;
        }
    }
}

Если разрыв выполняется из набора вложенных циклов, то завершается только самый внутренний цикл, в котором выполняется разрыв. (Так же, как стандартный C)

оператор break выходит из самого внутреннего цикла. Для выхода из внешнего цикла потребуется дополнительная инструкция test and break.

точно так же, как и последние, как правило, так:

for(i=0;i<a;i++){  
 for(j=0;j<a;j++){
  if(Something_goes_wrong){
   i=a;
   break;
   }
 }
}

просто для усмешки, как насчет изменения этой проверки true / false в метод и использования return отчетность:

- (bool) checkTrueFalse: parameters{

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

         if (...) {
            return true;
         }

      }
   }
   return false;
}

Comments

    Ничего не найдено.