Как я могу вырваться из двух вложенных циклов for в Objective-C?
у меня есть два цикла для вложенных, как это:
for(...) {
for(...) {
}
}
Я знаю, что есть break заявление. Но я смущен, если он ломает оба цикла или только тот, в котором он был вызван? Мне нужно сломать оба, как только я вижу, что нет смысла повторять больше раз.
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