Могу ли я использовать break для выхода из нескольких вложенных циклов for?

можно использовать для выхода из нескольких вложенных for петли? Если да, то как бы вы это сделали? Можете ли вы также контролировать, сколько петель выходов break?

17 ответов


AFAIK, C++ не поддерживает циклы именования, как Java и другие языки. Вы можете использовать goto или создать значение флага, который вы используете. В конце каждого цикла проверяем значение флага. Если установлено значение true, вы можете выйти из этой итерации.


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


другой подход к выходу из вложенного цикла-разложить оба цикла на отдельную функцию и return от этой функции, когда вы хотите выйти.

конечно, это вызывает другой аргумент о том, следует ли вам когда-либо явно return из функции в любом месте, кроме конца.


просто добавить явный ответ, используя lambdas:

  for (int i = 0; i < n1; ++i) {
    [&] {
      for (int j = 0; j < n2; ++j) {
        for (int k = 0; k < n3; ++k) {
          return; // yay we're breaking out of 2 loops here
        }
      }
    }();
  }

конечно, этот шаблон имеет определенные ограничения и, очевидно, только C++11, но я думаю, что это довольно полезно.


перерыв выйдет только из внутреннего цикла, содержащего его.

можно использовать перейти чтобы вырваться из любого количества циклов.

конечно перейти часто Считаются Вредными.

правильно ли использовать функцию break[...]?

использование break и goto может затруднить рассуждение о правильности программы. См. здесь для обсуждения этого: Дийкстра не был сумасшедшим.


хотя этот answear уже был представлен, я думаю, что хороший подход заключается в следующем:

for(unsigned int z = 0; z < z_max; z++)
{
    bool gotoMainLoop = false;
    for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
    {
        for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
        {
                          //do your stuff
                          if(condition)
                            gotoMainLoop = true;
        }
    }

}

Как насчет этого?

for(unsigned int i=0; i < 50; i++)
{
    for(unsigned int j=0; j < 50; j++)
    {
        for(unsigned int k=0; k < 50; k++)
        {
            //Some statement
            if (condition)
            {
                j=50;
                k=50;
            }
        }
    }
}

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

void foo()
{
    for(unsigned int i=0; i < 50; i++)
    {
        for(unsigned int j=0; j < 50; j++)
        {
            for(unsigned int k=0; k < 50; k++)
            {
                // If condition is true
                return;
            }
        }
    }
}

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

for (;;)
  for (;;)
    goto theEnd;
theEnd:

goto может быть очень полезно для разрыва вложенных циклов

for (i = 0; i < 1000; i++) {
    for (j = 0; j < 1000; j++) {
        for (k = 0; k < 1000; k++) {
             for (l = 0; l < 1000; l++){
                ....
                if (condition)
                    goto break_me_here;
                ....
            }
        }
    }
}

break_me_here:
// Statements to be executed after code breaks at if condition

на break оператор завершает выполнение ближайшего вшита do, for, switch или while заявление, в котором он появляется. Управление переходит к оператору, который следует за завершенным оператором.

С в MSDN.


Я думаю goto действует в этом случае:

для имитации break/continue ты хочешь:

перерыв

for ( ;  ;  ) {
    for ( ;  ;  ) {
        /*Code here*/
        if (condition) {
            goto theEnd;
        }
    }
}
theEnd:

дальше

for ( ;  ; ) {
    for ( ;  ;  ) {
        /*Code here*/
        if (condition) {
            i++;
            goto multiCont;
        }
    }
    multiCont:
}

другие языки, такие как PHP принимать параметр для перерыва (т. е. перерыв 2;), чтобы указать количество уровней вложенности цикла, которые вы хотите разорвать, однако c++ не. Вам придется разобраться в этом, используя логическое значение, которое вы установите в false до цикла значение true в цикле, если вы хотите перерыв, плюс условный перерыв после вложенного цикла, проверки, если логическое значение true, и перерыв, если да.


Я знаю, это старый пост . Но я бы предложил более логичный и простой ответ.

for(unsigned int i=0; i < 50; i++)
    {
        for(unsigned int j=0; j < conditionj; j++)
        {
            for(unsigned int k=0; k< conditionk ; k++)
            {
                // If condition is true

                j= conditionj;
               break;
            }
        }
    }

вы можете использовать try...поймать.

try {
    for(int i=0; i<10; ++i) {
        for(int j=0; j<10; ++j) {
            if(i*j == 42)
                throw 0; // this is something like "break 2"
        }
    }
}
catch(int e) {} // just do nothing
// just continue with other code

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


  while (i<n) {
    bool shouldBreakOuter = false;
    for (int j=i + 1; j<n; ++j) {
      if (someCondition) {
          shouldBreakOuter = true;
      }
    }

    if (shouldBreakOuter == true)
      break;

  }

выход из for-loop немного странен для меня, так как семантика for-loop обычно указывает, что он будет выполняться определенное количество раз. Однако это не плохо во всех случаях; если вы ищете что-то в коллекции и хотите сломать после того, как найдете его, это полезно. Вырваться из вложенных циклов, но это не возможно в C++, в других языках с помощью меченых перерыв. Вы можете использовать ярлык и goto, но это может дать вам изжогу на ночь..? Похоже, самое лучшее, хотя вариант.