Как я могу вырваться из двух вложенных циклов в Objective-C?
У меня есть два цикла, вложенные следующим образом:
for(...) {
for(...) {
}
}
Я знаю, что существует инструкция break
. Но я смущен, если он сломает обе петли или просто ту, в которой она была вызвана? Мне нужно сломать оба, как только я увижу, что не имеет смысла повторять больше раз.
Ответы
Ответ 1
break вырывается из одного цикла, но вы можете добавить проверку на внешний цикл, который прерывается, когда внутренний разрыв.
bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
for ( ... ) {
if (...) {
dobreak = true;
break;
}
}
}
Ответ 2
Если использование goto упрощает код, тогда это будет уместно.
for (;;)
{
for (;;)
{
break; /* breaks inner loop */
}
for (;;)
{
goto outer; /* breaks outer loop */
}
}
outer:;
Ответ 3
Оператор 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. */
}
}
}
Ответ 4
Помимо уже упомянутой переменной флага или goto вы можете throw исключение Objective-C:
@try {
for() {
for() {
@throw ...
}
}
}
@catch{
...
}
Ответ 5
Другие упомянули, как вы можете установить флаг или использовать 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;
}
Pseudocode, не тестировался, но вы поняли идею.
Ответ 6
Оператор break выйдет из цикла в области, который является родительским циклом. Если вы хотите выйти из второго цикла, вы также можете использовать логическую переменную, которая находится в области обеих циклов
bool isTerminated = false;
for (...)
{
if (!isTerminated)
{
for(...)
{
...
isTerminated = true;
break;
}
}
else
{
break;
}
}
Ответ 7
Вероятно, самый простой способ - использовать переменную "флаг"
for(i=0; i<10 && (done==false); i++)
for(j=0;j< 10; j++){
..
..
if(...){done=true; break;}
}
Ответ 8
Сменить счетчик верхнего контура перед разрывом
for(i=0; i<10 ; i++)
for(j=0;j< 10; j++){
..
..
i = 10;
break;
}
Ответ 9
Другим решением является фактор второго цикла в функции:
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;
}
}
}
Ответ 10
Если разрыв выполняется из набора вложенных циклов, завершается только самый внутренний цикл, в котором выполняется разрыв. (Так же, как стандарт C)
Ответ 11
Оператор break вырывается из самого внутреннего цикла. Для выхода из внешнего цикла потребуется дополнительный тест и оператор break.
Ответ 12
Точно так же, как и последние, обычно такие:
for(i=0;i<a;i++){
for(j=0;j<a;j++){
if(Something_goes_wrong){
i=a;
break;
}
}
}
Ответ 13
Просто для усмешек, как насчет изменения этой проверки true/false в методе и с помощью операторов return
:
- (bool) checkTrueFalse: parameters{
for ( ...) {
for ( ... ) {
if (...) {
return true;
}
}
}
return false;
}