Как вырваться из вложенных циклов?

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

Есть ли другой способ разбить все петли? (Пожалуйста, не используйте goto stmt .)

 for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; j++) { if(condition) { // both of the loops need to break and control will go to stmt2 } } } stmt2 

    Как насчет:

     if(condition) { i = j = 1000;break; } 

    Нет, не портите удовольствие с break . Это последнее оставшееся действительное использование goto 🙂

    Если это не так, вы можете использовать флаги, чтобы вырваться из глубоких вложенных циклов.

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

    Обобщены – чтобы вырваться из вложенных циклов:

    1. использовать goto
    2. флаги использования
    3. вытеснять циклы на отдельные вызовы функций

    Не удалось устоять, не включая xkcd здесь 🙂

    введите описание изображения здесь

    источник

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

     bool stop = false; for (int i = 0; (i < 1000) && !stop; i++) { for (int j = 0; (j < 1000) && !stop; j++) { if (condition) stop = true; } } 

    Один из способов состоит в том, чтобы поместить все вложенные петли в функцию и вернуться из внутреннего большинства циклов из-за необходимости вырваться из всех циклов.

     function() { for(int i=0; i<1000; i++) { for(int j=0; j<1000;j++) { if (condition) return; } } } 

    Я думаю, что goto решит проблему

     for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; i++) { if (condition) { goto end; } } } end: stmt2 

    Вам понадобится логическая переменная, если вы хотите ее прочитать:

     bool broke = false; for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; i++) { if (condition) { broke = true; break; } } if (broke) break; } 

    Если вы хотите, чтобы он был менее читаемым, вы можете присоединиться к логической оценке:

     bool broke = false; for(int i = 0; i < 1000 && !broke; i++) { for(int j = 0; j < 1000; i++) { if (condition) { broke = true; break; } } } 

    В качестве окончательного способа вы можете аннулировать исходный цикл:

     for(int i = 0; i < size; i++) { for(int j = 0; j < 1000; i++) { if (condition) { i = size; break; } } } 

    Используйте этот мудрый совет от команды LLVM:

    «Превратить петли предикатов в функции предиката»

    Видеть:

    http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions

    Если вам нужны значения i и j, это должно работать, но с меньшей производительностью, чем другие

     for(i;i< 1000; i++){ for(j; j< 1000; j++){ if(condition) break; } if(condition) //the same condition break; } 
     for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; i++) { if(condition) { goto end; } } end: 

    Внимание: этот ответ показывает действительно неясную конструкцию.

    Если вы используете GCC, проверьте эту библиотеку . Как и в PHP, break может принять количество вложенных циклов, которые вы хотите закрыть. Вы можете написать примерно так:

     for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; j++) { if(condition) { // break two nested enclosing loops break(2); } } } 
     i = 0; do { for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here! { if (condition) { break; } } ++i; } while ((i < 1000) && !condition); 
     int i = 0, j= 0; for(i;i< 1000; i++){ for(j; j< 1000; j++){ if(condition){ i = j = 1001; break; } } } 

    Разломит оба петель.

     for(int i = 0; i < 1000; i++) { for(int j = 0; j < 1000; i++) { if(condition) { func(para1, para2...); return; } } } func(para1, para2...) { stmt2; } 
    Давайте будем гением компьютера.