Viele Antworten scheinen sich auf die Fähigkeit zu konzentrieren, als Grund für die Forderung nach dem Durchfallen zu fallenbreak
Aussage .
Ich glaube, es war einfach ein Fehler, vor allem, weil bei der Entwicklung von C nicht annähernd so viel Erfahrung mit der Verwendung dieser Konstrukte vorhanden war.
Peter Van der Linden macht den Fall in seinem Buch "Expert C Programming":
Wir haben die Sun C-Compilerquellen analysiert, um festzustellen, wie oft der Standard-Fall-Through verwendet wurde. Das Sun ANSI C-Compiler-Frontend verfügt über 244 switch-Anweisungen, von denen jede durchschnittlich sieben Fälle aufweist. In nur 3% aller dieser Fälle tritt ein Durchfall auf.
Mit anderen Worten, das normale Schaltverhalten ist in 97% der Fälle falsch . Es ist nicht nur in einem Compiler - im Gegenteil, wo in dieser Analyse Fall Through verwendet wurde, war es häufig für Situationen, die in einem Compiler häufiger auftreten als in anderer Software, beispielsweise beim Kompilieren von Operatoren, die entweder einen oder zwei Operanden haben können ::
switch (operator->num_of_operands) {
case 2: process_operand( operator->operand_2);
/* FALLTHRU */
case 1: process_operand( operator->operand_1);
break;
}
Das Durchfallen von Fällen ist so weit verbreitet, dass es sogar eine spezielle Kommentarkonvention gibt, die oben zeigt, dass "dies wirklich einer der 3% der Fälle ist, in denen ein Durchfallen gewünscht wurde".
Ich denke, es war eine gute Idee für C #, am Ende jedes Fallblocks eine explizite Sprunganweisung zu verlangen (während immer noch mehrere Fallbezeichnungen gestapelt werden können - solange es nur einen einzigen Anweisungsblock gibt). In C # kann immer noch ein Fall in einen anderen fallen - Sie müssen nur den Fall explizit machen, indem Sie mit a zum nächsten Fall springengoto
.
Es ist schade, dass Java die Gelegenheit nicht genutzt hat, um von der C-Semantik abzubrechen.
In vielerlei Hinsicht ist c nur eine saubere Schnittstelle zu Standard-Assembly-Redewendungen. Beim Schreiben einer von der Sprungtabelle gesteuerten Flusssteuerung hat der Programmierer die Wahl, durch die "Steuerstruktur" zu fallen oder aus dieser herauszuspringen, und ein Herausspringen erfordert eine explizite Anweisung.
Also macht c dasselbe ...
quelle
NULL
. (Fortsetzung im nächsten Kommentar.)NUL
-terminierte Saiten sind fast die schlechteste Idee, die es je gab.DO
Schleife.Um Duffs Gerät zu implementieren, natürlich:
quelle
Wenn Fälle so konzipiert wären, dass sie implizit brechen, könnten Sie nicht durchfallen.
Wenn der Schalter so ausgelegt wäre, dass er nach jedem Fall implizit ausbricht, hätten Sie keine Wahl. Die Schaltkastenstruktur wurde so gestaltet, dass sie flexibler ist.
quelle
Die case-Anweisungen in einer switch-Anweisung sind einfach Bezeichnungen.
Wenn Sie einen Wert einschalten, führt die switch-Anweisung im Wesentlichen ein goto aus auf das Etikett mit dem passenden Wert.
Dies bedeutet, dass die Unterbrechung erforderlich ist, um zu vermeiden, dass der Code unter dem nächsten Etikett angezeigt wird.
Was den Grund betrifft, warum es auf diese Weise implementiert wurde, ist, dass der Fall-Through-Charakter einer switch-Anweisung in einigen Szenarien nützlich sein kann. Beispielsweise:
quelle
break
wo es gebraucht wird. 2) Wenn die Reihenfolge der case-Anweisungen geändert wird, kann der Fallthrough dazu führen, dass der falsche Fall ausgeführt wird. Daher finde ich die Handhabung von C # viel besser (explizitgoto case
für Fallthrough, außer für leere Falletiketten).break
in C # zu vergessen - am einfachsten ist es, wenn Sie nicht möchten, dass acase
etwas tut, sondern vergessen, a hinzuzufügenbreak
(vielleicht haben Sie sich so in den erklärenden Kommentar vertieft oder wurden bei einigen abgerufen andere Aufgabe): Die Ausführung wird nur bis zumcase
Folgenden durchgeführt. 2) Ermutigengoto case
heißt unstrukturierte "Spaghetti" -Codierung fördern - es kann zu versehentlichen Zyklen kommen (case A: ... goto case B; case B: ... ; goto case A;
), insbesondere wenn die Fälle in der Datei getrennt und in Kombination schwer zu erfassen sind. In C ++ ist der Durchfall lokalisiert.Um Dinge zuzulassen wie:
Stellen Sie sich das
case
Schlüsselwort alsgoto
Label vor und es kommt viel natürlicher.quelle
if(0)
am Ende des ersten Falles ist böse und sollte nur verwendet werden, wenn das Ziel darin besteht, den Code zu verschleiern.Es verhindert die Duplizierung von Code, wenn mehrere Fälle denselben Code (oder denselben Code nacheinander) ausführen müssen.
Da es auf der Ebene der Assemblersprache egal ist, ob Sie zwischen den einzelnen Fällen wechseln oder nicht, gibt es sowieso keinen Overhead für Fall-Through-Fälle. Warum also nicht zulassen, da sie in bestimmten Fällen erhebliche Vorteile bieten?
quelle
Ich bin zufällig auf einen Fall gestoßen, bei dem Strukturen Werte in Vektoren zugewiesen wurden: Dies musste so erfolgen, dass der Rest der Mitglieder in verbleiben würde, wenn der Datenvektor kürzer als die Anzahl der Datenelemente in der Struktur wäre ihren Standardwert. In diesem Fall war das Weglassen
break
sehr nützlich.quelle
Wie viele hier angegeben haben, soll ein einzelner Codeblock für mehrere Fälle funktionieren. Dies sollte bei Ihren switch-Anweisungen häufiger vorkommen als bei dem in Ihrem Beispiel angegebenen "Codeblock pro Fall".
Wenn Sie einen Codeblock pro Fall ohne Durchfall haben, sollten Sie möglicherweise einen if-elseif-else-Block verwenden, da dies angemessener erscheint.
quelle