Schaltanweisung
Im Computerprogrammiersprachen, a Schaltanweisung ist eine Art von Auswahlsteuerungsmechanismus, mit der der Wert von a zulässig ist Variable oder Ausdruck, um die zu ändern Steuerfluss der Programmausführung über Suche und Karte.
Switch -Anweisungen funktionieren etwas ähnlich wie bei der wenn
Aussage verwendet in Programmiersprachen wie C/C ++, C#, Visual Basic .net, Java und existiert in den meisten hohen Ebenen Imperative Programmierung Sprachen wie Pascal, Ada, C/C ++, C#, Visual Basic .net, Javaund in vielen anderen Arten von Sprache, die solche verwenden Schlüsselwörter wie Schalter
, Fall
, auswählen
oder prüfen
.
Switch -Anweisungen sind in zwei Hauptvarianten erhältlich gehe zu. Die Hauptgründe für die Verwendung eines Schalters sind die Verbesserung der Klarheit, die Reduzierung der ansonsten wiederholenden Codierung und (wenn die Heuristik zulassen) bieten auch das Potenzial für eine schnellere Ausführung durch einfacher Compiler -Optimierung in vielen Fällen.
Schalter (das Alter) { Fall 1: printf("Du bist einer."); Unterbrechung; Fall 2: printf("Du bist zwei."); Unterbrechung; Fall 3: printf("Du bist drei."); Fall 4: printf("Du bist drei oder vier."); Unterbrechung; Ursprünglich: printf("Du bist nicht 1,2,3 oder 4!"); } |
Geschichte
In seinem Text von 1952 Einführung in Metamathematik, Stephen Kleene formell bewiesen, dass die Fallfunktion (die if-then-else-Funktion ist ihre einfachste Form) a primitive rekursive Funktion, wo er den Begriff definiert Definition nach Fällen
auf folgende Art:
- "#F. Die Funktion φ definiert so
- φ (x1 , ... , xn ) =
- φ1(x1 , ... , xn ) Wenn q1(x1 , ... , xn ),
- . . . . . . . . . . . .
- φm(x1 , ... , xn ) Wenn qm(x1 , ... , xn ),
- φM+1(x1 , ... , xn ) Andernfalls,
- φ (x1 , ... , xn ) =
- wo q1 , ... , Qm sind gegenseitig ausschließende Prädikate (oder φ (x1 , ... , xn) hat den Wert, der durch die erste Klausel angegeben ist, die gilt) primitiv rekursiv in φ1, ..., φM+1, Q1, ..., QM+1.[1]
Kleene liefert einen Beweis dafür in Bezug auf die booleschen rekursiven Funktionen "Sign-of" SG () und "nicht Zeichen von" ~ sg () (Kleene 1952: 222-223); Der erste gibt 1 zurück, wenn seine Eingabe positiv ist und –1, wenn seine Eingabe negativ ist.
Boolos-Burgess-Jeffrey machen die zusätzliche Beobachtung, dass "Definition nach Fällen" beides sein muss gegenseitig exklusiv und Kollektiv erschöpfend. Auch sie bieten einen Beweis für die primitive Rekursivität dieser Funktion (Boolos-Burgess-Jeffrey 2002: 74-75).
Die IF-Then-Else ist die Grundlage der McCarthy Formalismus: seine Verwendung ersetzt sowohl die primitive Rekursion als auch die mu-operator.
Typische Syntax
In den meisten Sprachen schreiben Programmierer mit einem oder zwei Schlüsselwörtern eine Switch -Anweisung über viele einzelne Zeilen. Eine typische Syntax beinhaltet:
- Der Erste
auswählen
, gefolgt von einem Ausdruck, der oft als die bezeichnet wird Kontrollausdruck oder Steuervariable der Switch -Anweisung - Nachfolgende Zeilen, die die tatsächlichen Fälle (die Werte) definieren, mit entsprechenden Aussagensequenzen für die Ausführung, wenn eine Übereinstimmung auftritt
- In Sprachen mit Falle Verhalten, a
Unterbrechung
Anweisung folgt normalerweise aFall
Erklärung zur Beendigung dieser Erklärung. [Wells] - In einigen Sprachen, z. B.,, Pl/iDer Kontrollausdruck ist optional; Wenn es keinen Kontrollausdruck gibt, beginnt jede Alternative mit a
WENN
Klausel mit einem booleschen Ausdruck und einer Übereinstimmung tritt für den ersten Fall auf, für den dieser Ausdruck true bewertet wird. Diese Verwendung ähnelt dem if/then/sonst/else Strukturen in einigen anderen Sprachen, z. B., Perl. - In einigen Sprachen, z. B.,, RexxEs ist kein Kontrollausdruck erlaubt und jede Alternative beginnt mit a
WENN
Klausel mit einem booleschen Ausdruck und einer Übereinstimmung tritt für den ersten Fall auf, für den dieser Ausdruck true bewertet wird.
Jede Alternative beginnt mit dem jeweiligen Wert oder der Liste von Werten (siehe unten), die die Steuervariable übereinstimmen kann und die die Steuerung an die Steuerung verursacht gehe zu die entsprechende Abfolge von Aussagen. Der Wert (oder die Liste/der Wertebereich) wird normalerweise von der entsprechenden Anweisungssequenz durch einen Dickdarm oder durch einen Implikationspfeil getrennt. In vielen Sprachen muss auch jedem Fall ein Schlüsselwort wie z. Fall
oder Wenn
.
Ein optionaler Standardfall ist normalerweise auch zulässig, angegeben durch a Ursprünglich
, Andernfalls
, oder anders
Stichwort. Dies wird ausgeführt, wenn keiner der anderen Fälle mit dem Kontrollausdruck übereinstimmt. In einigen Sprachen wie C, wenn kein Fall übereinstimmt und die Ursprünglich
wird weggelassen Schalter
Aussage leitet einfach aus. In anderen, wie PL/I wird ein Fehler aufgeworfen.
Semantik
Semantisch gibt es zwei Hauptformen von Switch -Anweisungen.
Die erste Form sind strukturierte Schalter, wie in Pascal, wo genau ein Zweig genommen wird und die Fälle als separate, exklusive Blöcke behandelt werden. Dies fungiert als verallgemeinerte wenn auch - ELSE bedingt, hier mit einer beliebigen Anzahl von Zweigen, nicht nur zwei.
Die zweite Form sind unstrukturierte Schalter, wie in C, wo die Fälle als Etiketten innerhalb eines einzelnen Blocks behandelt werden, und der Schalter fungiert als verallgemeinerter Goto. Diese Unterscheidung wird als Behandlung von Falsch bezeichnet, die unten ausgearbeitet wird.
Durchfallen
In vielen Sprachen wird nur der passende Block ausgeführt, und dann wird die Ausführung am Ende der Switch -Anweisung fortgesetzt. Dazu gehören die Pascal Familie (Objekt Pascal, Modula, Oberon, ADA usw.) sowie Pl/i, moderne Formen von Forran und BASIC Dialekte, die von Pascal, den meisten funktionalen Sprachen und vielen anderen beeinflusst werden. Damit mehrere Werte denselben Code ausführen können (und dies vermeiden muss Doppelter Code), Pascal-Sprachen ermöglichen eine beliebige Anzahl von Werten pro Fall, die als von Kommas getrennte Liste, als Bereich oder als Kombination angegeben sind.
Sprachen, die aus der C -Sprache abgeleitet sind, und allgemeiner von den von Forran's beeinflusst berechnete Goto, stattdessen dürfen die Kontrolle zum Matching -Fall wechselt und dann die Ausführung fortgesetzt ("fällt durch") zu den mit dem verbundenen Aussagen nächste Fall im Quelltext. Auf diese Weise können mehrere Werte ohne spezielle Syntax mit demselben Punkt übereinstimmen: Sie sind nur mit leeren Körpern aufgeführt. Werte können im Fall des Codes mit Code speziell konditioniert werden. In der Praxis wird die Falte normalerweise mit a verhindert Unterbrechung
Schlüsselwort am Ende des passenden Körpers, der die Ausführung des Switch -Blocks verlässt. Dies kann jedoch Fehler verursachen, da der Programmierer das Einfügen des Programmiers vergisst Unterbrechung
Aussage. Dies wird daher von vielen gesehen[2] als Sprachwarde und warnte in einigen Lint -Tools vor. Syntaktisch werden die Fälle als Etiketten, nicht als Blöcke interpretiert, und die Anweisungen für Switch and Break ändern explizit den Kontrollfluss. Einige von C beeinflusste Sprachen wie z. JavaScriptBehalten Sie den Standard -Falle bei, während andere Falte entfernen oder nur unter besonderen Umständen zulassen. Bemerkenswerte Variationen dazu in der C-Familie umfassen C#, in denen alle Blöcke mit a beendet werden müssen Unterbrechung
oder Rückkehr
Es sei denn, der Block ist leer (d. H. Die Falle wird verwendet, um mehrere Werte anzugeben).
In einigen Fällen liefern Sprachen optionale Falle. Zum Beispiel, Perl fällt nicht standardmäßig durch, aber ein Fall kann dies ausdrücklich mit a tun fortsetzen
Stichwort. Dies verhindert ein unbeabsichtigtes Falle, lässt dies jedoch nach Belieben zu. Ähnlich, Verprügeln Standardeinstellungen, wenn Sie nicht durchfallen, wenn Sie beendet werden ;;
, aber fallenfällt[3] mit Und
oder ;; &; &
stattdessen.
Ein Beispiel für eine Switch -Anweisung, die auf Falsch beruht Duffs Gerät.
Zusammenstellung
Compiler optimieren wie zum Beispiel GCC oder Klang kann eine Switch -Anweisung in beide a zusammenstellen Zweigtisch oder ein binäre Suche durch die Werte in den Fällen.[4] In einer Zweig -Tabelle kann die Switch -Anweisung mit einer kleinen, konstanten Anzahl von Anweisungen ermitteln, die ausführen sollen, ohne eine Liste von Vergleiche durchlaufen zu müssen, während eine binäre Suche nur eine logarithmische Anzahl von Vergleiche erfordert, gemessen in der Anzahl der Fälle in Fällen in Die Switch -Anweisung.
Normalerweise ist die einzige Methode, um herauszufinden, ob diese Optimierung aufgetreten ist Montage oder Maschinensprache Ausgabe, der vom Compiler erzeugt wurde.
Vorteile und Nachteile
In einigen Sprachen und Programmierumgebungen die Verwendung von a Fall
oder Schalter
Die Aussage wird einer äquivalenten Reihe von als überlegen angesehen wenn sonst wenn Aussagen, weil es ist:
- Einfacher zu debuggen (z. B. Einstellen von Haltepunkten in Code vs. eine Anruftabelle, wenn der Debugger keine bedingte Haltepunktfunktion hat)
- Leichter für eine Person zu lesen
- Einfacher zu verstehen und folglich einfacher zu pflegen
- Feste Tiefe: Eine Abfolge von "if sonst if" -Anweisungen kann eine tiefe Verschachtelung ergeben, was die Kompilierung schwieriger macht (insbesondere in automatisch generierten Code)
- Einfacher zu überprüfen, ob alle Werte behandelt werden. Compiler können eine Warnung ausstellen, wenn einige Enum -Werte nicht behandelt werden.
Zusätzlich an optimiert Die Implementierung kann viel schneller ausführen als die Alternative, da sie häufig unter Verwendung eines indizierten implementiert wird Zweigtisch.[5] Beispielsweise ist es weitaus effizienter als die Alternative, wenn es korrekt implementiert ist, bei der korrekten Implementierung eine Auswahl des Programmflusses zu Anweisungspfadlängen wesentlich. Bei der Implementierung als solche wird eine Switch -Anweisung im Wesentlichen a Perfekter Hash.
In Bezug auf die Kontroll-Flow-DiagrammEine Switch -Anweisung besteht aus zwei Knoten (Eingang und Ausgang) sowie einer Kante zwischen ihnen für jede Option. Im Gegensatz dazu hat eine Sequenz von "if ... sonst wenn ... sonst wenn" Anweisungen einen zusätzlichen Knoten für jeden anderen Fall als den ersten und letzten sowie eine entsprechende Kante haben. Das resultierende Kontroll-Flow-Diagramm für die Sequenzen von "if" hat somit viel mehr Knoten und fast doppelt so viele Kanten, wobei diese keine nützlichen Informationen hinzufügen. Die einfachen Zweige in den IF -Anweisungen sind jedoch konzeptionell einfacher als der komplexe Zweig einer Switch -Anweisung. Bezüglich zyklomatische Komplexitätdiese beiden Optionen erhöhen es durch k–1 Wenn gegeben k Fälle.
Ausdrücke wechseln
Ausdrücke wechseln werden eingeführt in Java SE 12, 19. März 2019, als Vorschau -Funktion. Hier kann ein ganzer Switch -Ausdruck verwendet werden, um einen Wert zurückzugeben. Es gibt auch eine neue Form von Case -Label, case L->
wo die rechte Seite ein einzelner Ausdruck ist. Dies verhindert jedoch auch den Sturz und erfordert, dass Fälle erschöpfend sind. In Java se 13 die Ertrag
Die Aussage wird eingeführt, und in Java SE 14 wird Switch -Ausdrücke zu einer Standard -Sprachfunktion.[6][7][8] Zum Beispiel:
int nägige = Schalter(Monat) { Fall Jan, BESCHÄDIGEN, KANN, Jul, August, Oktober, Dez -> 31; Fall Apr, Jun, Sep, Nov. -> 30; Fall Feb -> { wenn (Jahr % 400 == 0) Ertrag 29; anders wenn (Jahr % 100 == 0) Ertrag 28; anders wenn (Jahr % 4 == 0) Ertrag 29; anders Ertrag 28; } };
Alternative Verwendungen
Viele Sprachen bewerten Ausdrücke im Inneren Schalter
Blöcke zur Laufzeit, die eine Reihe weniger offensichtlicher Verwendungszwecke für die Konstruktion ermöglichen. Dies verbietet bestimmte Compiler -Optimierungen, ist daher häufiger in dynamischen und Skriptsprachen, bei denen die verbesserte Flexibilität wichtiger ist als der Leistungsaufwand.
Php
Zum Beispiel in Php, Eine Konstante kann als "Variable" verwendet werden, um es zu überprüfen, und die erste Fallanweisung, die diese Konstante bewertet, wird ausgeführt:
Schalter (Stimmt) { Fall ($ x == 'hallo'): Foo(); Unterbrechung; Fall ($ z == 'Hallo'): Unterbrechung; } Schalter (5) { Fall $ x: Unterbrechung; Fall $ y: Unterbrechung; }
Diese Funktion ist auch nützlich, um mehrere Variablen gegen einen Wert anstelle einer Variablen mit vielen Werten zu überprüfen. COBOL unterstützt auch diese Form (und andere Formen) in der AUSWERTEN
Aussage. Pl/ich hat eine alternative Form der AUSWÄHLEN
Aussage, bei der der Kontrollausdruck insgesamt weggelassen wird und der erste WENN
das bewertet Stimmt wird ausgeführt.
Rubin
Im Rubinaufgrund seiner Handhabung von ===
Gleichheit, die Anweisung kann verwendet werden, um die Klasse der Variablen zu testen:
Fall Eingang Wenn Array dann stellt "Eingabe ist ein Array!" Wenn Hash dann stellt "Eingabe ist ein Hash!" Ende
Ruby gibt auch einen Wert zurück, der einer Variablen zugeordnet werden kann, und es erfordert nicht tatsächlich die Fall
Parameter haben (ein bisschen wie eine verhalten sonst wenn
Aussage):
Katzenfutter = Fall Wenn Katze.das Alter <= 1 Junior Wenn Katze.das Alter > 10 Senior anders normal Ende
Assembler
Eine Switch -Anweisung in Montagesprache:
Schalter: CMP Ah, 00H je a CMP Ah, 01H je b JMP swTend ; Keine Fälle übereinstimmen oder "Standard" Code hier a: drücken Ah MOV al, 'a' MOV Ah, 0EH MOV BH, 00H int 10H Pop Ah JMP swTend ; Äquivalent zu "brechen" b: drücken Ah MOV al, 'b' MOV Ah, 0EH MOV BH, 00H int 10H Pop Ah JMP swTend ; Äquivalent zu "brechen" ... swTend:
Ausnahmebehandlung
Eine Reihe von Sprachen implementieren eine Form der Switch -Anweisung in AusnahmebehandlungWenn eine Ausnahme in einem Block angehoben wird, wird je nach Ausnahme ein separater Zweig ausgewählt. In einigen Fällen ist auch ein Standardzweig vorhanden, wenn auch keine Ausnahme erhoben wird, ebenfalls vorhanden. Ein frühes Beispiel ist Modula-3, die die verwenden VERSUCHEN
...AUSSER
Syntax, wo jeder AUSSER
definiert einen Fall. Dies wird auch in gefunden Delphi, Scala, und Visual Basic .net.
Alternativen
Einige Alternativen zu Switch -Anweisungen können sein:
- Eine Reihe von ansonsten Bedingungen Das untersucht den Ziel jeweils einen Wert. Falschverhalten kann mit einer Abfolge von erreicht werden wenn Bedingungen ohne die ohne die anders Klausel.
- A Nachschlagwerk, was als Schlüssel enthält, die
Fall
Werte und, als Werte, den Teil unter demFall
Aussage.
- (In einigen Sprachen sind nur tatsächliche Datentypen als Werte in der Nachschlagetabelle zulässig. In anderen Sprachen ist es auch möglich zuzuweisen Funktionen Als Suchentabellenwerte werden die gleiche Flexibilität wie ein real
Schalter
Aussage. Sehen Steuerungstabelle Artikel für weitere Einzelheiten dazu). - Lua unterstützt keine Fall-/Switch -Anweisungen.[9] Diese Suchtechnik ist eine Möglichkeit zum Implementieren
Schalter
Aussagen in der LUA-Sprache, die kein Einbau hatSchalter
.[9] - In einigen Fällen sind Suchtabellen effizienter als nichtoptimiert
Schalter
Aussagen Da viele Sprachen die Tabellen -Lookups optimieren können, während Switch -Anweisungen nicht optimiert werden, es sei denn, der Wertebereich ist mit wenigen Lücken gering. Ein nicht optimiertes, nichtbinäre Suche Die Suche wird jedoch mit ziemlicher Sicherheit langsamer sein als ein nicht optimierter Schalter oder das äquivalente Mehrfach ansonsten Aussagen.
- (In einigen Sprachen sind nur tatsächliche Datentypen als Werte in der Nachschlagetabelle zulässig. In anderen Sprachen ist es auch möglich zuzuweisen Funktionen Als Suchentabellenwerte werden die gleiche Flexibilität wie ein real
- A Steuerungstabelle (Dies kann als einfache Nachbesserungstabelle implementiert werden) kann auch so angepasst werden, dass sie bei Bedarf mehrere Bedingungen für mehrere Eingänge berücksichtigen, und weist normalerweise eine größere „visuelle Kompaktheit“ auf als ein äquivalenter Schalter (der viele Aussagen belegen kann).
- Musteranpassung, was zur Implementierung von Schaltfunktionen in vielen verwendet wird funktional Sprachen.
Siehe auch
Verweise
- ^ "Definition nach Fällen", Kleene 1952: 229
- ^ Van der Linden, Peter (1994). Experte C -Programmierung: Deep C -Geheimnisse, p. 38. Prentice Hall, Eaglewood Cliffs. ISBN0131774298.
- ^ seit Version 4.0, veröffentlicht im Jahr 2009.
- ^ Vlad Lazarenko. Von der Switch -Anweisung bis zum Maschinencode
- ^ Guntheroth, Kurt (27. April 2016). Optimiert C ++. O'Reilly Media. p. 182. ISBN 9781491922033.
- ^ "JEP 325: Switch Expressions (Vorschau)". openjdk.java.net. Abgerufen 2021-04-28.
- ^ "JEP 354: Switch Expressions (zweite Vorschau)". openjdk.java.net. Abgerufen 2021-04-28.
- ^ "JEP 361: Switch Expressions". openjdk.java.net. Abgerufen 2021-04-28.
- ^ a b Schalteranweisung in lUA
Weitere Lektüre
- Stephen Kleene, 1952 (10. Nachdruck 1991), Einführung in Metamathematik, North-Holland Publishing Company, Amsterdam NL, ISBN0-7204-2103-9
- George Boolos, John Burgess, und Richard Jeffrey, 2002, Berechnbarkeit und Logik: vierte Ausgabe, Cambridge University Press, Cambridge UK, ISBN0-521-00758-5 Taschenbuch. vgl. Seite 74-75.