Pętla C # - przerwa kontra kontynuacja

797

W pętli C # (możesz swobodnie odpowiadać na inne języki), jaka jest różnica między break i kontynuuj jako sposobem na opuszczenie struktury pętli i przejście do następnej iteracji?

Przykład:

foreach (DataRow row in myTable.Rows)
{
    if (someConditionEvalsToTrue)
    {
        break; //what's the difference between this and continue ?
        //continue;
    }
}
Seibar
źródło
2
post na blogu z kulminacją poniżej adamthings.com/post/2012/07/26/…
Adam
8
continue;zatrzyma przetwarzanie prądu rowi przejdzie do następnego row z kolekcji. Z drugiej strony break;pozostawi foreachinstrukcję całkowicie, a pozostałe wiersze nigdy nie zostaną przetworzone.
Jeppe Stig Nielsen

Odpowiedzi:

1500

breakcałkowicie continueopuści pętlę, po prostu przeskoczy bieżącą iterację.

Na przykład:

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

    DoSomeThingWith(i);
}

Przerwa spowoduje zamknięcie pętli przy pierwszej iteracji - DoSomeThingWithnigdy nie zostanie wykonana. To tutaj:

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

    DoSomeThingWith(i);
}

Nie wykona DoSomeThingWithza i = 0, ale pętla będzie nadal i DoSomeThingWithbędą realizowane do i = 1celu i = 9.

Michael Stum
źródło
2
Dlaczego ich brak aparatów ortodontycznych trwa nadal - wiem, że działa bez nich, ale dlaczego?
George Willcox,
52
@GeorgeWillcox Moje młodsze, bardziej głupie ja nie nauczyło się jeszcze wartości używania aparatów ortodontycznych, zawsze. (Są one opcjonalne w języku C # dla pojedynczych instrukcji, ale ich nie umieszczenie ułatwia późniejsze wprowadzenie błędu. Zobacz także programmers.stackexchange.com/a/16530/6342 )
Michael Stum
386

Naprawdę łatwym sposobem na zrozumienie tego jest umieszczenie słowa „pętla” po każdym ze słów kluczowych. Warunki mają teraz sens, jeśli są czytane jak codzienne frazy.

break pętla - pętla jest przerywana i zatrzymuje się.

continue pętla - pętla kontynuuje wykonywanie przy następnej iteracji.

JeremiahClark
źródło
105

break powoduje, że licznik programu wyskakuje z zakresu najbardziej wewnętrznej pętli

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

Działa tak

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

kontynuuj przeskakuje do końca pętli. W pętli for kontynuuj przeskakiwanie do wyrażenia przyrostowego.

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

    printf("%d", i);
}

Działa tak

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

    printf("%d", i);

    CONTINUE:;
}
Średnik
źródło
2
Zauważyłem, że wiele pętli używa tylko standardowej forpętli, ale czy to zadziała w przypadku whilepętli testowanych przed i po ? Że gotoprowadzi mnie notacji wierzyć tak, ale potrzebuję trochę weryfikacji.
Daniel Park,
1
@Daniel, w przypadku PĘTLI możesz użyć funkcji PRZERWA i KONTYNUUJ, nie ma problemu.
Amila
@DanielPark Zarówno dla while(„wstępnie przetestowane”), jak i do- while(„przetestowane”), po continue;spełnieniu instrukcji, następną rzeczą, która się wydarzy, jest ocena warunku pętli w celu podjęcia decyzji, czy należy wykonać dodatkową iterację. Oczywiście, break;gdy warunek pętli nie jest sprawdzany, pętla jest po prostu całkowicie opuszczana. Tak więc gotoanalogia jest dobra dla zrozumienia tego aspektu.
Jeppe Stig Nielsen
37

Zawsze byłem zdezorientowany, czy powinienem użyć przerwy, czy kontynuować. To pomaga mi pamiętać:

Kiedy korzystać z opcji Break vs Kontynuuj?

  1. Przerwa - to jak zerwanie. To smutne, rozstajecie się. Pętla została zakończona.

Złamać

  1. Kontynuuj - oznacza, że ​​odpoczniesz dzisiaj i jutro wszystko uporządkujesz (tzn. Pomiń obecną iterację)!

Kontyntynuj

BKSpurgeon
źródło
Podzielę się tym z moim partnerem. Może być Kontynuuj należy zmienić nazwę na GetOverIt, a Break należy zmienić nazwę na MoveOnForward. Nic dziwnego, że nazywamy się maniakami, w jaki sposób Break ma sens? Brzmi destrukcyjnie. A jeden, który należy dodać to - STOP, lub jeszcze lepiej EndIt - naprawi wiele błędów i sprawi, że C-sharp będzie naprawdę ostry.
Mike
Znowu w powódź Ta sama stara wycieczka, to była wtedy Popełniłem wielki błąd Postaraj się to kiedyś zobaczyć
Talal Zahid
@TalalZahid nie rozumiem?
BKSpurgeon
28

breakforeachcałkowicie zatrzyma pętlę, przejdzie continuedo następnego DataRow.

palmsey
źródło
20

Jest więcej niż kilka osób, które nie lubią breaki continue. Ostatnia skarga, jaką o nich widziałam, była w JavaScript: The Good Parts autorstwa Douglasa Crockforda. Uważam jednak, że czasami użycie jednego z nich naprawdę upraszcza rzeczy, zwłaszcza jeśli twój język nie zawiera pętli do-whilelub do-untilstylu.

Zwykle używam breakw pętlach, które szukają czegoś na liście. Po znalezieniu nie ma sensu kontynuować, więc równie dobrze możesz zrezygnować.

używam continue gdy robię coś z większością elementów listy, ale nadal chcę pominąć kilka.

breakOświadczenie również jest przydatna, gdy odpytywanie dla ważnej odpowiedzi od kogoś lub czegoś. Zamiast:

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

Możesz wyeliminować pewne powielanie i użyć:

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

do-untilPętla już wcześniej wspomniano jest bardziej eleganckie rozwiązanie dla tego konkretnego problemu:

Do:
    Ask a question
    Until the answer is valid

Bez powielania i nie breakjest również potrzebny.

yukondude
źródło
13

Wszyscy podali bardzo dobre wyjaśnienie. Nadal zamieszczam swoją odpowiedź, aby podać przykład, czy to może pomóc.

// 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] ";
}

Oto wynik:

0 [wydrukowano] 1 [wydrukowano] 2 [wydrukowano]

Zatem 3 [Wydrukowane] i 4 [Wydrukowane] nie będą wyświetlane, ponieważ występuje przerwa, gdy 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] ";
}

Oto wynik:

0 [wydrukowano] 1 [wydrukowano] 2 [wydrukowano] 4 [wydrukowano]

Tak więc 3 [Wydrukowane] nie będzie wyświetlane, ponieważ jest kontynuowane, gdy i == 3

Pritom Nandy
źródło
7

Złamać

Break zmusza pętlę do natychmiastowego wyjścia.

Kontyntynuj

Robi to przeciwieństwo przerwy. Zamiast przerywać pętlę, natychmiast pętli ponownie, pomijając resztę kodu.

Sona
źródło
1
Kontynuuj również sprawdzanie stanu pętli :)
Grantly
1
Continuenie jest przeciwieństwem break, breakzatrzymuje pętlę, continuezatrzymuje bieżącą iterację.
Steven
6

Prosta odpowiedź:

Break natychmiast opuszcza pętlę.
Kontynuuj rozpoczyna przetwarzanie następnego elementu. (Jeśli istnieją, przeskakując do linii oceny for / while)

Maltrap
źródło
6

Przez przykład

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

Drukuje 1, 2, 3 (na osobnych liniach).

Dodaj warunek przerwania dla i = 2

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

    Console.WriteLine(i);
}

Teraz pętla drukuje 1 i zatrzymuje się.

Zastąp przerwę kontynuacją.

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

    Console.WriteLine(i);
}

Teraz do zapętlenia wydruków 1 i 3 (pomijanie 2).

W ten sposób breakzatrzymuje pętlę, a continueprzeskakuje do następnej iteracji.

Pułkownik Panika
źródło
5

Ruby niestety jest nieco inny. PS: Moja pamięć jest trochę mglista, więc przepraszam, jeśli się mylę

zamiast break / kontynuuj ma break / next, które zachowują się tak samo pod względem pętli

Pętle (jak wszystko inne) są wyrażeniami i „zwracają” ostatnią rzecz, którą zrobili. W większości przypadków uzyskanie wartości zwracanej z pętli jest bezcelowe, więc wszyscy po prostu to robią

a = 5
while a < 10
    a + 1
end

Możesz to jednak zrobić

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

JEDNAK, dużo kodu ruby ​​„emuluje” pętlę za pomocą bloku. Kanonicznym przykładem jest

10.times do |x|
    puts x
end

Ponieważ ludzie znacznie częściej chcą robić rzeczy z wynikiem bloku, w tym miejscu robi się bałagan. break / next oznacza różne rzeczy w kontekście bloku.

break wyskoczy z kodu, który wywołał blok

next pominie resztę kodu w bloku i „zwróci” to, co określisz, do dzwoniącego bloku. Bez przykładów nie ma to sensu.

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.

Więc tak. Ruby jest niesamowity, ale ma kilka okropnych skrzynek. Jest to drugi najgorszy, jaki widziałem w latach użytkowania :-)

Orion Edwards
źródło
5

Proszę pozwolić mi powiedzieć, co oczywiste: pamiętaj, że dodanie ani przerwania, ani kontynuowania, wznowi twój program; tzn. zostałem uwięziony dla określonego błędu, a następnie po zalogowaniu go chciałem wznowić przetwarzanie, a między kolejnymi wierszami było więcej zadań związanych z kodem, więc po prostu pozwoliłem mu przejść.

David Hall
źródło
3

Aby całkowicie zerwać z pętli foreach, stosuje się break ;

Aby przejść do następnej iteracji w pętli, używana jest kontynuacja ;

Przerwa jest przydatna, jeśli przeglądasz kolekcję Obiektów (takich jak Wiersze w tabeli danych) i szukasz określonego dopasowania, gdy znajdziesz to dopasowanie, nie musisz kontynuować przez pozostałe wiersze, więc chcesz przerwać na zewnątrz.

Opcja Kontynuuj jest przydatna, gdy osiągniesz to, czego potrzebujesz po stronie iteracji pętli. Zwykle będziesz kontynuować po if .

Gopesh Sharma
źródło
2

jeśli nie chcesz używać break , po prostu zwiększ wartość I w taki sposób, że spowoduje to, że warunek iteracji będzie fałszywy, a pętla nie wykona się przy następnej iteracji.

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
}
Umair Khalid
źródło
0

Jeśli chodzi o inne języki:

'VB
For i=0 To 10
   If i=5 then Exit For '= break in C#;
   'Do Something for i<5
next

For i=0 To 10
   If i=5 then Continue For '= continue in C#
   'Do Something for i<>5...
Next
dba
źródło