Czy używanie break
instrukcji wewnątrz for
pętli jest złą praktyką ?
Powiedz, szukam wartości w tablicy. Porównaj wewnątrz pętli for i gdy zostanie znaleziona wartość, break;
aby wyjść z pętli for.
Czy to zła praktyka? Widziałem alternatywę używany: zdefiniować zmienną vFound
i ustawić go na true, gdy wartość jest znaleźć i sprawdzić vFound
w for
warunku instrukcji. Ale czy konieczne jest utworzenie nowej zmiennej tylko w tym celu?
Pytam w kontekście normalnej pętli for w C lub C ++.
PS: Wytyczne kodowania MISRA odradzają stosowanie przerwy.
break
goto
Odpowiedzi:
Wiele odpowiedzi tutaj, ale jeszcze tego nie widziałem:
Większość „niebezpieczeństw” związanych z używaniem
break
lubcontinue
w pętli for jest negowana, jeśli piszesz uporządkowane, łatwe do odczytania pętle. Jeśli treść twojej pętli obejmuje kilka długości ekranu i ma wiele zagnieżdżonych podbloków, tak, możesz łatwo zapomnieć, że jakiś kod nie zostanie wykonany po przerwie. Jeśli jednak pętla jest krótka i trafna, cel instrukcji break powinien być oczywisty.Jeśli pętla staje się zbyt duża, zamiast tego użyj jednego lub więcej dobrze nazwanych wywołań funkcji w pętli. Jedynym prawdziwym powodem, aby tego uniknąć, są wąskie gardła przetwarzania.
źródło
Nie, przerwa to właściwe rozwiązanie.
Dodanie zmiennej boolowskiej utrudnia czytanie kodu i dodaje potencjalne źródło błędów.
źródło
goto
do wyrwania się z zagnieżdżonych pętli poziomu 2+ - ponieważ nie mabreak(level)
Możesz znaleźć wszelkiego rodzaju profesjonalny kod z instrukcjami „break”. Używanie tego w razie potrzeby ma sens. W twoim przypadku ta opcja jest lepsza niż tworzenie osobnej zmiennej tylko w celu wyjścia z pętli.
źródło
Używanie
break
jak równieżcontinue
wfor
pętli jest w porządku.Upraszcza kod i poprawia jego czytelność.
źródło
Daleko od złej praktyki, Python (i inne języki?) Rozszerzył strukturę
for
pętli , tak że jej część zostanie wykonana tylko wtedy, gdy pętla tego nie zrobibreak
.Wynik:
Równoważny kod bez
break
i to przydatneelse
:źródło
Nie ma nic złego w używaniu instrukcji break, ale zagnieżdżone pętle mogą być mylące. Aby poprawić czytelność, wiele języków ( przynajmniej Java ) obsługuje łamanie etykiet, co znacznie poprawi czytelność.
Powiem, że instrukcje break (and return) często zwiększają cykliczną złożoność, co utrudnia udowodnienie, że kod działa poprawnie we wszystkich przypadkach.
Jeśli rozważasz użycie przerwy podczas iteracji sekwencji dla określonego elementu, możesz ponownie rozważyć strukturę danych używaną do przechowywania danych. Używanie czegoś takiego jak zestaw lub mapa może zapewnić lepsze wyniki.
źródło
for
pętli.break jest całkowicie akceptowalnym poleceniem do użycia (tak samo jest continue , btw). Chodzi o czytelność kodu - o ile nie masz zbyt skomplikowanych pętli i tym podobnych, wszystko jest w porządku.
To nie tak, że byli w tej samej lidze co goto . :)
źródło
Zasada ogólna: jeśli przestrzeganie zasady wymaga zrobienia czegoś bardziej niezręcznego i trudnego do przeczytania, a następnie złamania reguły, należy ją złamać.
W przypadku zapętlania się, dopóki czegoś nie znajdziesz, napotkasz problem rozróżnienia znalezionego i nie znalezionego, gdy wyjdziesz. To jest:
Więc w porządku, możesz ustawić flagę lub zainicjować wartość „znalezioną” na null. Ale
Dlatego generalnie wolę przekierowywać moje wyszukiwania do funkcji:
Pomaga to również uporządkować kod. W głównym wierszu „znajdź” staje się pojedynczą instrukcją, a gdy warunki są złożone, są zapisywane tylko raz.
źródło
break
, próbuję znaleźć sposób na refaktoryzację kodu w funkcję, aby móc użyćreturn
zamiast tego.To zależy od języka. Chociaż możesz tutaj sprawdzić zmienną boolowską:
nie można tego zrobić podczas iterowania po tablicy:
W każdym razie
break
sprawiłoby, że oba kody byłyby bardziej czytelne.źródło
W twoim przykładzie nie znasz liczby iteracji pętli for . Dlaczego nie używać while pętli zamiast, który pozwala liczba iteracji być nieokreślona na początku?
Nie jest zatem konieczne stosowanie przerwy statemement w ogóle, jak pętla może być lepiej zaznaczono jako while pętli.
źródło
Zgadzam się z innymi, którzy zalecają używanie
break
. Oczywiste pytanie brzmi: dlaczego ktoś miałby zalecać inaczej? Cóż ... kiedy używasz break, pomijasz resztę kodu w bloku i pozostałe iteracje. Czasami powoduje to błędy, na przykład:zasób uzyskany na górze bloku może zostać zwolniony na dole (jest to prawdą nawet dla bloków wewnątrz
for
pętli), ale ten krok zwolnienia może zostać przypadkowo pominięty, gdy „przedwczesne” wyjście jest spowodowanebreak
instrukcją (w „nowoczesnym” C ++, „RAII” jest używany do obsługi tego w niezawodny i bezpieczny sposób: w zasadzie destruktory obiektów niezawodnie zwalniają zasoby bez względu na sposób zamykania zakresu)ktoś może zmienić test warunkowy w
for
instrukcji, nie zauważając, że istnieją inne zdelokalizowane warunki wyjściaOdpowiedź ndim wskazuje, że niektórzy ludzie mogą unikać
break
s, aby utrzymać względnie spójny czas wykonywania pętli, ale porównujeszbreak
z użyciem boolowskiej zmiennej kontrolnej wczesnego wyjścia, gdzie to się nie sprawdzaOd czasu do czasu ludzie obserwujący takie błędy zdają sobie sprawę, że można im zapobiec / złagodzić tę zasadę „bez przerw”… rzeczywiście, istnieje cała powiązana strategia „bezpieczniejszego” programowania zwanego „programowaniem strukturalnym”, gdzie każda funkcja powinna mieć pojedynczy punkt wejścia i wyjścia (tj. brak goto, brak wcześniejszego powrotu). Może wyeliminować niektóre błędy, ale niewątpliwie wprowadza inne. Dlaczego oni to robią?
źródło
break
. Uniknęli tego, ale nie przemyśleli warunków, które zastąpiły użycie przerwy.Jest całkowicie ważny w użyciu
break
- jak zauważyli inni, nigdzie nie jest w tej samej lidze cogoto
.Chociaż możesz chcieć użyć
vFound
zmiennej, gdy chcesz sprawdzić poza pętlą, czy wartość została znaleziona w tablicy. Również z punktu widzenia łatwości konserwacji, posiadanie wspólnej flagi sygnalizującej kryteria wyjścia może być przydatne.źródło
Dokonałem analizy kodu źródłowego, nad którym obecnie pracuję (40 000 linii JavaScript).
Znalazłem tylko 22
break
stwierdzenia, z których:switch
instrukcjach (w sumie mamy tylko 3 instrukcje switch!).for
pętli - kod, który od razu sklasyfikowałem jako do ponownego przekształcenia w osobne funkcje i zastąpionyreturn
instrukcją.break
wewnętrznąwhile
... Pobiegłem,git blame
żeby zobaczyć, kto napisał to gówno!Więc według moich statystyk: jeśli
break
jest używany na zewnątrzswitch
, jest to zapach kodu.Szukałem też
continue
wypowiedzi. Nie znaleziono.źródło
Nie widzę żadnego powodu, dla którego byłaby to zła praktyka POD WZGLĘDEM, że chcesz zakończyć przetwarzanie w tym momencie.
źródło
W świecie osadzonych jest dużo kodu, który wykorzystuje następującą konstrukcję:
To bardzo ogólny przykład, wiele rzeczy dzieje się za kurtyną, w szczególności przerw. Nie używaj tego jako standardowego kodu, po prostu próbuję zilustrować przykład.
Osobiście uważam, że nie ma nic złego w pisaniu pętli w ten sposób, o ile zostanie podjęta odpowiednia uwaga, aby nie pozostawać w pętli w nieskończoność.
źródło
continue
w logice aplikacji znajdują się instrukcje. Są tam?Zależy od twojego przypadku użycia. Istnieją aplikacje, w których czas wykonywania pętli for musi być stały (np. W celu spełnienia pewnych ograniczeń czasowych lub ukrycia wewnętrznych danych przed atakami opartymi na czasie).
W takich przypadkach ma sens nawet ustawienie flagi i sprawdzanie wartości flagi tylko PO wykonaniu wszystkich
for
iteracji pętli. Oczywiście wszystkie iteracje pętli for muszą uruchamiać kod, który nadal zajmuje mniej więcej tyle samo czasu.Jeśli nie zależy Ci na czasie wykonywania ... użyj
break;
i,continue;
aby kod był łatwiejszy do odczytania.źródło
Na regułach MISRA 98, które są używane w mojej firmie w C dev, instrukcja break nie powinna być używana ...
Edycja: przerwa jest dozwolona w MISRA '04
źródło
Oczywiście
break;
rozwiązaniem jest zatrzymywanie pętli for lub foreach. Użyłem go w php w pętli foreach i for i stwierdziłem, że działa.źródło
Nie zgadzam się!
Dlaczego miałbyś ignorować wbudowaną funkcjonalność pętli for, aby stworzyć własną? Nie musisz wymyślać koła na nowo.
Myślę, że bardziej sensowne jest umieszczanie czeków na górze pętli for
lub jeśli najpierw musisz przetworzyć wiersz
W ten sposób możesz napisać funkcję, która wykona wszystko i stworzy znacznie bardziej przejrzysty kod.
Lub jeśli twój stan jest skomplikowany, możesz też przenieść ten kod!
„Kod Profesjonalny”, pełen przerw, nie brzmi dla mnie jak kod profesjonalny. Brzmi jak leniwe kodowanie;)
źródło
break
twierdzi, że jest to dla czytelności kodu. Teraz spójrz ponownie na szalony stan długości 5 mil w pętlach powyżej ...