Wiele odpowiedzi wydaje się skupiać się na zdolności do upadku jako na przyczynie żądania break
stwierdzenia.
Uważam, że był to po prostu błąd, głównie dlatego, że gdy projektowano C, nie było tak dużego doświadczenia w zakresie wykorzystania tych konstrukcji.
Peter Van der Linden przedstawia taki przypadek w swojej książce „Expert C Programming”:
Przeanalizowaliśmy źródła kompilatora Sun C, aby zobaczyć, jak często używany był domyślny błąd. Interfejs kompilatora Sun ANSI C ma 244 instrukcje przełączające, z których każda ma średnio siedem przypadków. Upadek występuje tylko w 3% wszystkich tych przypadków.
Innymi słowy, normalne zachowanie przełącznika jest nieprawidłowe w 97% przypadków. Nie dotyczy to tylko kompilatora - wręcz przeciwnie, tam, gdzie fall through używano w tej analizie, często dotyczyło to sytuacji, które występują częściej w kompilatorze niż w innym oprogramowaniu, na przykład podczas kompilowania operatorów, które mogą mieć jeden lub dwa operandy :
switch (operator->num_of_operands) {
case 2: process_operand( operator->operand_2);
/* FALLTHRU */
case 1: process_operand( operator->operand_1);
break;
}
Upadek przypadku jest tak powszechnie uznawany za wadę, że istnieje nawet specjalna konwencja komentarzy, pokazana powyżej, która mówi lintowi, że „jest to naprawdę jeden z tych 3% przypadków, w których upadek był pożądany”.
Myślę, że dobrym pomysłem dla C # było wymaganie jawnej instrukcji skoku na końcu każdego bloku przypadku (przy jednoczesnym umożliwieniu układania wielu etykiet przypadków - o ile istnieje tylko jeden blok instrukcji). W języku C # nadal możesz mieć jeden przypadek przechodzić do drugiego - wystarczy, że przejdziesz bezpośrednio przez przejście do następnego przypadku przy użyciu pliku goto
.
Szkoda, że Java nie skorzystała z okazji, aby zerwać z semantyką C.
Na wiele sposobów c jest po prostu przejrzystym interfejsem do standardowych idiomów asemblera. Pisząc sterowanie przepływem sterowane tablicą skoków, programista ma do wyboru wypadnięcie lub wyskoczenie ze „struktury sterowania”, a wyskoczenie wymaga wyraźnej instrukcji.
Więc c robi to samo ...
źródło
NULL
. (Ciąg dalszy w następnym komentarzu.)NUL
zakończone struny to chyba najgorszy pomysł na świecie.DO
pętli Fortran .Aby wdrożyć urządzenie Duffa, oczywiście:
źródło
Gdyby sprawy miały załamać się niejawnie, to nie można by tego dokonać.
Gdyby przełącznik został zaprojektowany tak, aby wyłamać się niejawnie po każdym przypadku, nie miałbyś wyboru. Konstrukcja obudowy przełącznika została zaprojektowana w taki sposób, aby była bardziej elastyczna.
źródło
Instrukcje case w instrukcjach switch są po prostu etykietami.
Po przełączeniu na wartości, instrukcja switch zasadniczo robi goto do etykiety o wartości dopasowania.
Oznacza to, że przerwa jest konieczna, aby uniknąć przejścia do kodu pod następną etykietą.
Jeśli chodzi o powód, dla którego została zaimplementowana w ten sposób - upadkowy charakter instrukcji przełącznika może być przydatny w niektórych scenariuszach. Na przykład:
źródło
break
gdzie jest to potrzebne. 2) Jeśli kolejność instrukcji przypadków zostanie zmieniona, przejście może spowodować uruchomienie niewłaściwej sprawy. Dlatego uważam, że obsługa języka C # jest znacznie lepsza (jawnagoto case
dla fallthrough, z wyjątkiem pustych etykiet wielkości liter).break
w C # - najprostszy jest to, gdy nie chceszcase
nic robić, ale zapomnisz dodaćbreak
(być może tak bardzo pochłonął cię komentarz wyjaśniający, albo ktoś cię wezwał inne zadanie): wykonanie przejdzie docase
poniższego. 2) zachęcającegoto case
jest zachęcanie do nieustrukturyzowanego kodowania „spaghetti” - możesz skończyć z przypadkowymi cyklami (case A: ... goto case B; case B: ... ; goto case A;
), zwłaszcza gdy przypadki są oddzielone w pliku i trudne do zrozumienia w kombinacji. W C ++ lokalizowane jest przejście przez.Aby zezwolić na takie rzeczy, jak:
Pomyśl o
case
słowie kluczowym jak ogoto
etykiecie i jest to o wiele bardziej naturalne.źródło
if(0)
pod koniec pierwszego przypadku jest złe i powinno być używane tylko wtedy, gdy celem jest zaciemnienie kodu.Eliminuje powielanie kodu, gdy kilka przypadków musi wykonać ten sam kod (lub ten sam kod w kolejności).
Ponieważ na poziomie języka asemblerowego nie ma znaczenia, czy przerwiesz każdy z nich, czy też nie, i tak nie ma żadnego narzutu za upadek przypadków, więc dlaczego nie pozwolić im, skoro oferują one znaczące korzyści w niektórych przypadkach.
źródło
Zdarzyło mi się natknąć się na przypadek przypisywania wartości w wektorach do struktur: trzeba było to zrobić w taki sposób, że jeśli wektor danych byłby krótszy niż liczba członków danych w strukturze, reszta członków pozostałaby w ich wartość domyślna. W takim przypadku pomijanie
break
było całkiem przydatne.źródło
Jak wiele osób tutaj wskazało, ma to pozwolić na działanie pojedynczego bloku kodu w wielu przypadkach. To powinno być częstsze występowanie do swoich sprawozdań przełączników niż „bloku kodu na wszelki wypadek” można określić w swoim przykładzie.
Jeśli masz blok kodu na przypadek bez upadku, być może powinieneś rozważyć użycie bloku if-elseif-else, ponieważ wydaje się to bardziej odpowiednie.
źródło