Цикл C # - разрыв против продолжения


797

В цикле C # (не стесняйтесь отвечать за другие языки), в чем разница между break и continue в качестве средства выхода из структуры цикла и перехода к следующей итерации?

Пример:

foreach (DataRow row in myTable.Rows)
{
    if (someConditionEvalsToTrue)
    {
        break; //what's the difference between this and continue ?
        //continue;
    }
}

2
сообщение в блоге с кульминацией ниже adamthings.com/post/2012/07/26/…
Адам

8
continue;остановит обработку текущего rowи перейдет к следующему row из коллекции. С другой стороны, полностью break;покинет foreachоператор, а остальные строки никогда не будут обработаны.
Джеппе Стиг Нильсен

Ответы:


1501

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

Например:

for (int i = 0; i < 10; i++) {
    if (i == 0) {
        break;
    }

    DoSomeThingWith(i);
}

Прерывание вызовет выход цикла на первой итерации - DoSomeThingWithникогда не будет выполнен. Это здесь:

for (int i = 0; i < 10; i++) {
    if(i == 0) {
        continue;
    }

    DoSomeThingWith(i);
}

Не будет выполняться DoSomeThingWithдля i = 0, но цикл будет продолжаться и DoSomeThingWithбудет выполняться для i = 1к i = 9.


2
Почему их брекеты продолжаются - я знаю, что это работает без них, но почему?
Джордж Уиллкокс,

52
@GeorgeWillcox Моя младшая, более глупая личность еще не научилась использовать скобки всегда. (Они являются необязательными в C # для отдельных операторов, но если их не ставить, будет легче ввести ошибку позже. Также см. Programmers.stackexchange.com/a/16530/6342 )
Michael Stum

386

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

break цикл - цикл прерывается и останавливается.

continue цикл - цикл продолжает выполняться со следующей итерации.


105

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

for(i = 0; i < 10; i++)
{
    if(i == 2)
        break;
}

Работает так

for(i = 0; i < 10; i++)
{
    if(i == 2)
        goto BREAK;
}
BREAK:;

продолжить прыжки до конца цикла. В цикле for продолжаются переходы к выражению приращения.

for(i = 0; i < 10; i++)
{
    if(i == 2)
        continue;

    printf("%d", i);
}

Работает так

for(i = 0; i < 10; i++)
{
    if(i == 2)
        goto CONTINUE;

    printf("%d", i);

    CONTINUE:;
}

2
Я заметил, что многие циклы здесь просто используют стандартный forцикл, но сработает ли это для whileциклов до и после тестирования ? Запись gotoзаставляет меня верить в это, но нужна некоторая проверка.
Даниэль Парк

1
@Daniel, для циклов WHILE вы можете использовать BREAK и CONTINUE, нет проблем.
Амила

@DanielPark Для обоих while(«предварительно протестированный») и do- while(«пост-протестированный») после выполнения continue;инструкции будет выполнено следующее: условие цикла оценивается для принятия решения о необходимости выполнения дополнительной итерации. Конечно, break;если условие цикла не проверено, цикл просто завершается полностью. Так что gotoаналогия хороша для понимания этого аспекта.
Джепп Стиг Нильсен

37

Раньше я всегда запутывался, должен ли я использовать разрыв или продолжить. Вот что помогает мне запомнить:

Когда использовать перерыв против продолжения?

  1. Разбить - это все равно что расстаться. Грустно, вы, ребята, расстаетесь. Цикл завершен.

Перемена

  1. Продолжить - означает, что вы собираетесь сегодня отдохнуть, а завтра все уладить (т.е. пропустить текущую итерацию)!

Продолжить


Поделюсь этим с моим партнером. Может быть, Continue следует переименовать в GetOverIt, а Break следует переименовать в MoveOnForward. Неудивительно, что нас зовут гики, а в чем смысл Break? Это звучит разрушительно. И то, что нужно добавить: STOP или, что еще лучше, EndIt, исправит много ошибок и сделает C-sharp действительно резким.
Майк

Снова в потоп То же самое старое путешествие, что было тогда, поэтому я совершил большую ошибку. Попробуй увидеть это однажды, мой путь
Талал Захид

@ TalalZahid я не понимаю?
BKSpurgeon

28

breakполностью остановит foreachцикл, continueперейдет к следующему DataRow.


20

Есть более чем несколько человек, которые не любят breakи continue. Последняя жалоба, которую я видел о них, была в JavaScript: Хорошие части Дугласа Крокфорда. Но я считаю, что иногда использование одного из них действительно упрощает вещи, особенно если ваш язык не включает цикл do-whileили do-untilстиль.

Я склонен использовать breakв циклах, которые что-то ищут в списке. После того, как найден, нет смысла продолжать, так что вы могли бы также выйти.

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

Это breakутверждение также пригодится при опросе на предмет правильного ответа от кого-то или чего-либо. Вместо:

Ask a question
While the answer is invalid:
    Ask the question

Вы можете устранить некоторые дубликаты и использовать:

While True:
    Ask a question
    If the answer is valid:
        break

do-untilЦикл , который я упоминал ранее это более элегантное решение для этой конкретной проблемы:

Do:
    Ask a question
    Until the answer is valid

Нет дублирования, и нет breakнеобходимости.


13

Все дали очень хорошее объяснение. Я все еще публикую свой ответ, чтобы привести пример, если это может помочь.

// break statement
for (int i = 0; i < 5; i++) {
    if (i == 3) {
        break; // It will force to come out from the loop
    }

    lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}

Вот вывод:

0 [напечатано] 1 [напечатано] 2 [напечатано]

Таким образом, 3 [Отпечатано] и 4 [Отпечатано] не будут отображаться, поскольку при i == 3 происходит перерыв.

//continue statement
for (int i = 0; i < 5; i++) {
    if (i == 3) {
        continue; // It will take the control to start point of loop
    }

    lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}

Вот вывод:

0 [напечатано] 1 [напечатано] 2 [напечатано] 4 [напечатано]

Так что 3 [Printed] не будет отображаться, так как есть продолжение, когда я == 3


7

Перемена

Разрыв заставляет петлю немедленно выйти.

Продолжить

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


1
Продолжить также проверяет состояние цикла :)
Grantly

1
Continueне является противоположностью break, breakостанавливает цикл, continueостанавливает текущую итерацию.
Стивен

6

Простой ответ:

Перерыв выходит из цикла немедленно.
Продолжить начинает обработку следующего элемента. (Если таковые имеются, переходя к линии оценки для / в течение)


6

Примером

foreach(var i in Enumerable.Range(1,3))
{
    Console.WriteLine(i);
}

Печать 1, 2, 3 (на отдельных строках).

Добавить условие разрыва при i = 2

foreach(var i in Enumerable.Range(1,3))
{
    if (i == 2)
        break;

    Console.WriteLine(i);
}

Теперь цикл печатает 1 и останавливается.

Замените разрыв на продолжение.

foreach(var i in Enumerable.Range(1,3))
{
    if (i == 2)
        continue;

    Console.WriteLine(i);
}

Теперь нужно зациклить отпечатки 1 и 3 (пропуская 2).

Таким образом, breakостанавливает цикл, тогда как continueпереходит к следующей итерации.


5

К сожалению, Ruby немного отличается. PS: моя память немного туманна, поэтому извиняюсь, если я ошибаюсь

вместо break / continue, он имеет break / next, который ведет себя одинаково с точки зрения циклов

Циклы (как и все остальное) являются выражениями и «возвращают» последнее, что они сделали. В большинстве случаев получение возвращаемого значения из цикла бессмысленно, поэтому каждый просто делает это

a = 5
while a < 10
    a + 1
end

Однако вы можете сделать это

a = 5
b = while a < 10
    a + 1
end # b is now 10

ОДНАКО, много кода ruby ​​«эмулирует» цикл, используя блок. Канонический пример

10.times do |x|
    puts x
end

Поскольку люди гораздо чаще хотят делать что-то с результатом блока, именно здесь он становится беспорядочным. break / next означает разные вещи в контексте блока.

перерыв выпрыгнет из кода, который вызвал блок

next пропустит остальную часть кода в блоке и вернет то, что вы указали, вызывающему блоку. Это не имеет никакого смысла без примеров.

def timesten
    10.times{ |t| puts yield t }
end


timesten do |x|
   x * 2
end
# will print
2
4
6
8 ... and so on


timesten do |x|
    break
    x * 2
end
# won't print anything. The break jumps out of the timesten function entirely, and the call to `puts` inside it gets skipped

timesten do |x|
    break 5
    x * 2
end
# This is the same as above. it's "returning" 5, but nobody is catching it. If you did a = timesten... then a would get assigned to 5

timesten do |x|
    next 5
    x * 2
end 
# this would print
5
5
5 ... and so on, because 'next 5' skips the 'x * 2' and 'returns' 5.

Так что да. Ruby потрясающий, но у него есть несколько ужасных угловых случаев. Это второй худший из тех, что я видел за годы его использования :-)


5

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


3

Чтобы полностью вырваться из цикла foreach, используется break ;

Для перехода к следующей итерации цикла используется продолжить ;

Разрыв полезен, если вы просматриваете коллекцию Объектов (например, Строки в Datatable), и вы ищете конкретное совпадение, когда вы находите это совпадение, нет необходимости переходить через оставшиеся строки, поэтому вы хотите разбить вне.

Продолжение полезно, когда вы выполнили то, что вам нужно для выполнения итерации цикла. Вы, как правило, продолжите после if .


2

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

for(int i = 0; i < list.Count; i++){
   if(i == 5)
    i = list.Count;  //it will make "i<list.Count" false and loop will exit
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.