Steuerfluss
Im Informatik, Steuerfluss (oder Kontrollfluss) ist die Reihenfolge, in der Individuum Aussagen, Anweisungen oder Funktionsaufrufe von einem Imperativ Programm sind hingerichtet oder bewertet. Die Betonung des explizite Kontrollflusss unterscheidet eine Imperative Programmierung Sprache von a deklarative Programmierung Sprache.
Innerhalb eines Imperativs Programmiersprache, a Steuerflussanweisung ist eine Aussage, die dazu führt, dass die Entscheidung getroffen wird, welcher von zwei oder mehr Wegen zu folgen ist. Zum Nicht-Strikt Funktionssprachen, Funktionen und Sprachkonstrukte existieren, um das gleiche Ergebnis zu erzielen, aber sie werden normalerweise nicht als Kontrollflussanweisungen bezeichnet.
Eine Reihe von Aussagen ist wiederum im Allgemeinen als strukturiert als Block, was zusätzlich zur Gruppierung auch a definiert a lexikalischer Bereich.
Interrupts und Signale sind Mechanismen mit niedriger Ebene, die den Kontrollfluss auf ähnliche Weise wie a verändern können Subroutinetreten aber normalerweise als Reaktion auf einen externen Reiz oder Ereignis auf (der auftreten kann asynchron), anstatt die Ausführung eines in der Reihe Steuerflussanweisung.
Auf der Stufe von Maschinensprache oder Montagesprache, Kontrollflussanweisungen funktionieren normalerweise, indem sie die ändern Programm zähler. Für einige Zentrale Verarbeitungseinheiten (CPUs) sind die einzigen verfügbaren Steuerflussanweisungen bedingt oder bedingungslos Zweig Anweisungen, ebenfalls als Sprünge bezeichnet.
Kategorien
Die Arten von Kontrollflussanweisungen, die von verschiedenen Sprachen gestützt werden, variieren, können jedoch nach ihrer Wirkung kategorisiert werden:
- Fortsetzung bei einer anderen Aussage (bedingungsvoll Zweig oder springen)
- Nur eine Reihe von Anweisungen ausführen, wenn eine Bedingung erfüllt ist (Auswahl - d. H., bedingter Zweig)
- Ausführen einer Reihe von Anweisungen Null oder mehr Male, bis ein gewisses Zustand erfüllt ist (d. H. Schleife - genauso wie bedingter Zweig)
- Ausführung einer Reihe entfernter Aussagen, wonach der Kontrollfluss normalerweise zurückgibt (Unterroutinen, Coroutinen, und Kontinuationen)
- Stoppen des Programms, Verhinderung einer weiteren Ausführung (bedingungsloser Stopp)
Primitive
Etiketten
A Etikett ist ein expliziter Name oder eine Nummer, die einer festen Position innerhalb der zugewiesen ist Quellcode, und auf die durch Kontrollflussanweisungen, die an anderer Stelle im Quellcode erscheinen, verwiesen werden. Ein Etikett markiert eine Position innerhalb des Quellcodees und hat keinen anderen Effekt.
Linien Nummern sind eine Alternative zu einem benannten Etikett, das in einigen Sprachen verwendet wird (wie z. BASIC). Sie sind ganze Zahlen Zu Beginn jeder Textzeile im Quellcode platziert. Sprachen, die diese verwenden, stellen häufig die Einschränkung auf, dass die Zeilenzahlen in jeder folgenden Zeile den Wert erhöhen müssen, erfordert jedoch möglicherweise nicht, dass sie aufeinanderfolgend sind. Zum Beispiel in Basic:
10 LASSEN X = 3 20 DRUCKEN X
In anderen Sprachen wie z. C und Ada, ein Etikett ist ein Kennung, normalerweise zu Beginn einer Linie und unmittelbar gefolgt von einem Dickdarm. Zum Beispiel in C:
Erfolg: printf("Die Operation war erfolgreich.\n");
Die Sprache Algol 60 Ermöglichte sowohl ganze Zahlen als auch Kennungen als Etiketten (beide von Kolons mit der folgenden Erklärung verknüpft), aber nur wenige, wenn auch immer Algol Varianten erlaubten ganze Zahlen. Frühzeitig Forran Compiler erlaubten nur ganze Zahlen als Etiketten. Ab Fortran-90 wurden auch alphanumerische Etiketten erlaubt.
Gehe zu
Das gehe zu Aussage (eine Kombination der englischen Wörter gehen und zuund entsprechend ausgesprochen) ist die grundlegendste Form der bedingungslosen Kontrollübertragung.
Obwohl die Stichwort Kann je nach Sprache entweder im oberen oder unteren Fall sein, es wird normalerweise als:
gehe zu Etikett
Die Auswirkung einer GOTO -Erklärung besteht darin, die nächste Aussage als die Aussage zu erzeugen, die bei (oder unmittelbar danach) auf dem angegebenen Etikett erscheint.
Goto -Aussagen waren als schädlich angesehen von vielen Informatikern, insbesondere von Dijkstra.
Unterroutinen
Die Terminologie für Unterroutinen variiert; Sie können alternativ als Routinen, Verfahren, Funktionen (insbesondere wenn sie Ergebnisse zurückgeben) oder Methoden (insbesondere wenn sie gehören Klassen oder Geben Sie Klassen ein).
In den 1950er Jahren waren die Computererinnerungen nach aktuellen Maßstäben sehr gering, sodass Unterroutinen hauptsächlich zur Reduzierung der Programmgröße verwendet wurden. Ein Stück Code wurde einmal geschrieben und dann viele Male von verschiedenen anderen Orten in einem Programm verwendet.
Heutzutage werden Unterroutinen häufiger verwendet, um ein Programm strukturierter zu gestalten, z. B. durch Isolieren eines Algorithmus oder der Versteckung einer Datenzugriffsmethode. Wenn viele Programmierer an einem Programm arbeiten, sind Unterprogramme eine Art von Art von Modularität Das kann helfen, die Arbeit zu teilen.
Reihenfolge
In der strukturierten Programmierung wird die geordnete Sequenzierung aufeinanderfolgender Befehle als eine der grundlegenden Kontrollstrukturen angesehen, die neben Iteration, Rekursion und Auswahl als Baustein für Programme verwendet werden.
Minimaler strukturierter Kontrollfluss
Im Mai 1966 veröffentlichten Böhm und Jacopini einen Artikel[1] in Kommunikation der ACM was zeigte, dass jedes Programm mit gehe zuS könnte in ein goto-freies Formular umgewandelt werden, das nur ausgewählt wird (wenn auch dann) und Loops (während der Zustand do xxx), möglicherweise mit doppelter Code und/oder der Zugabe von booleschen Variablen (True/False Flags). Spätere Autoren zeigten, dass die Auswahl durch Schleifen (und noch mehr booleale Variablen) ersetzt werden kann.
Dass ein solcher Minimalismus möglich ist, bedeutet nicht, dass er notwendigerweise wünschenswert ist; Computern brauchen theoretisch nur nur Ein Maschinenanweis (Subtrahieren Sie eine Zahl von einer anderen und verzweigen, wenn das Ergebnis negativ ist), aber praktische Computer haben Dutzende oder sogar Hunderte von Maschinenanweisungen.
Was Böhm und Jacopinis Artikel zeigten, war, dass alle Programme goto-frei sein konnten. Andere Untersuchungen zeigten, dass Kontrollstrukturen mit einem Eintrag und einem Ausgang viel einfacher zu verstehen waren als jede andere Form, hauptsächlich weil sie überall als Aussage verwendet werden konnten, ohne den Kontrollfluss zu stören. Mit anderen Worten, sie waren es komponierbar. (Spätere Entwicklungen, wie z. Nicht-strenge Programmiersprachen - und in jüngerer Zeit komponierbar Software -Transaktionen - haben diese Strategie fortgesetzt und Komponenten von Programmen noch frei komponierbar.)
Einige Akademiker verfolgten einen puristischen Ansatz für das Ergebnis von Böhm -Jacopini und argumentierten, dass selbst Anweisungen wie Unterbrechung
und Rückkehr
Aus der Mitte der Schleifen sind schlechte Praxis, da sie im Böhm -Jacopini -Beweis nicht benötigt werden, und somit befürworteten sie, dass alle Schleifen einen einzigen Ausstiegspunkt haben sollten. Dieser puristische Ansatz ist in der Sprache verkörpert Pascal (Entworfen in den Jahren 1968–1969), das bis Mitte der neunziger Jahre das bevorzugte Instrument für das Unterrichten von Einführungsprogrammen in der Wissenschaft war.[2] Die direkte Anwendung des Böhm -Jacopini -Theorems kann dazu führen, dass zusätzliche lokale Variablen in das strukturierte Diagramm eingeführt werden und auch zu einigen führen können Code -Duplikation.[3] Pascal ist von beiden Problemen und nach empirischen Studien von zitiert durch diese Probleme beeinflusst Eric S. RobertsStudent -Programmierer hatten Schwierigkeiten, korrekte Lösungen in Pascal für mehrere einfache Probleme zu formulieren, einschließlich des Schreibens einer Funktion zum Durchsuchen eines Elements in einem Array. Eine Studie von 1980 von Henry Shapiro, die von Roberts zitiert wurde Mitte einer Schleife.[2]
Kontrollstrukturen in der Praxis
Die meisten Programmiersprachen mit Kontrollstrukturen haben ein anfängliches Schlüsselwort, das die Art der Kontrollstruktur anzeigt.[Klarstellung erforderlich] Sprachen teilen sich dann, ob Kontrollstrukturen ein endgültiges Schlüsselwort haben oder nicht.
- Kein endgültiges Schlüsselwort: Algol 60, C, C ++, Haskell, Java, Pascal, Perl, Php, Pl/i, Python, Power Shell. Solche Sprachen benötigen eine Möglichkeit, Aussagen zu gruppieren:
- Algol 60 und Pascal:
Start
...Ende
- C, C ++, Java, Perl, PHP und PowerShell: geschweifte Klammern
{
...}
- Pl/i:
TUN
...ENDE
- Python: Gebrauch Einzug Ebene (siehe Off-Side-Regel)
- Haskell: entweder Einzug Level oder lockige Klammern können verwendet werden und sie können frei gemischt werden
- Lua: Verwendungszwecke
tun
...Ende
- Algol 60 und Pascal:
- Finale Schlüsselwort: Ada, Algol 68, Modula-2, Forran 77, Mytyl, Visual Basic. Die Formen des endgültigen Schlüsselworts variieren:
- ADA: Das endgültige Schlüsselwort ist
Ende
+ Platz + Erstes Schlüsselwort, z. B.,wenn
...Ende wenn
,Schleife
...Endschleife
- Algol 68, Mythryl: Erstes Schlüsselwort rückwärts geschrieben, z. B.,
wenn
...fi
,Fall
...ESAC
- FORTRAN 77: Das endgültige Schlüsselwort ist
ENDE
+ Erstes Schlüsselwort, z. B.,WENN
...Endif
,TUN
...Enddo
- Modula-2: Gleiches endgültiges Schlüsselwort
ENDE
für alles - Visual Basic: Jede Kontrollstruktur hat ein eigenes Schlüsselwort.
Wenn
...Ende wenn
;Zum
...Nächste
;Tun
...Schleife
;Während
...Wend
- ADA: Das endgültige Schlüsselwort ist
Auswahl
If-then- (sonst) Aussagen
Bedingte Ausdrücke und bedingte Konstrukte sind Merkmale von a Programmiersprache die unterschiedliche Berechnungen oder Aktionen durchführen, je nachdem, ob ein Programmierer spezifiziert ist Boolesche Bedingung bewertet zu wahr oder falsch.
-
Wenn ... goto
. Eine Form, die in unstrukturierten Sprachen gefunden wurde und eine typische Anweisung für Maschinencode nachahmt, würde zu (GOTO) einer Etikett oder einer Zeilennummer springen, wenn der Zustand erfüllt wurde. -
Wenn.. dann .. (endif)
. Anstatt auf einen Sprung beschränkt zu sein, könnte eine einfache Aussage oder eine verschachtelte Blocks dem damaligen Schlüsselwort folgen. Dies ist eine strukturierte Form. -
Wenn.. dann..else .. (endif)
. Wie oben, aber mit einer zweiten Aktion, die ausgeführt wird, wenn die Bedingung falsch ist. Dies ist eine der häufigsten Formen mit vielen Variationen. Einige benötigen ein TerminalEndif
andere nicht. C und verwandte Sprachen erfordern kein Terminalschlüsselwort oder ein 'dann', sondern erfordern Klammern um die Bedingung. - Bedingte Aussagen können und sind häufig in anderen bedingten Aussagen verschachtelt. Einige Sprachen erlauben
ANDERS
undWENN
kombiniert werden inElseif
, vermeiden die Notwendigkeit, eine Reihe von zu habenEndif
oder andere endgültige Aussagen am Ende einer zusammengesetzten Aussage.
Pascal: | Ada: | C: | Shell-Skript: | Python: | Lispeln: |
---|---|---|---|---|---|
wenn a > 0 dann Writeln("Jawohl") anders Writeln("nein"); | wenn a > 0 dann Put_line("Jawohl"); anders Put_line("nein"); Ende wenn; | wenn (a > 0) { printf("Jawohl"); } anders { printf("nein"); } | wenn [ $ a -Gt 0 ]; dann Echo "Jawohl" anders Echo "nein" fi | wenn a > 0: drucken("Jawohl") anders: drucken("nein") | (Prinzessing (wenn (Plusp a) "Jawohl" "nein")) |
Weniger häufige Variationen umfassen:
- Einige Sprachen, wie z. Forran, haben eine Dreiweg oder Arithmetik wennTesten, ob ein numerischer Wert positiv, negativ oder Null ist.
- Einige Sprachen haben eine funktional Form von an
wenn
Aussage zum Beispiel Lisps'sKond
. - Einige Sprachen haben eine Operator Form von an
wenn
Aussage wie C's ternärer Operator. - Perl Ergänzung eines C-Stils
wenn
mitWenn
undwenn nicht
. - Smalltalk Verwendet
Wenn wahr
undIffalse
Nachrichten zur Implementierung von Bedingungen und nicht für ein grundlegendes Sprachkonstrukt.
Fall- und Schaltanweisungen
Anweisungen wechseln (oder Fallanweisungen, oder Multiway -Zweige) Vergleichen Sie einen gegebenen Wert mit bestimmten Konstanten und ergreifen Sie Maßnahmen gemäß der ersten Übereinstimmung. In der Regel wird eine Standardaktion ("sonst", "sonst") vorgesehen, wenn keine Übereinstimmung erfolgreich ist. Switch -Anweisungen können Compiler -Optimierungen ermöglichen, wie z. Nachschlagetabellen. Im Dynamische Sprachen, die Fälle sind möglicherweise nicht auf konstante Ausdrücke beschränkt und können sich auf erstrecken Musteranpassungwie in der Shell-Skript Beispiel rechts, wo die *)
implementiert den Standardfall als Glob Übereinstimmung mit einer String. Falllogik kann auch in funktionaler Form implementiert werden, wie in Sql's dekodieren
Aussage.
Pascal: | Ada: | C: | Shell-Skript: | Lispeln: |
---|---|---|---|---|
Fall Somechar von 'a': Actionona; 'x': Actiononx; "y",'z':Actiononyandz; anders Actiononnomatch; Ende; | Fall Somechar ist Wenn 'a' => Actionona; Wenn 'x' => Actiononx; Wenn 'y' | 'z' => Actiononyandz; Wenn Andere => Actiononnomatch; Ende; | Schalter (Somechar) { Fall 'a': Actionona; Unterbrechung; Fall 'x': Actiononx; Unterbrechung; Fall "y": Fall 'z': Actiononyandz; Unterbrechung; Ursprünglich: Actiononnomatch; } | Fall $ somechar in a) Actionona ;; x) Actiononx ;; [yz])) Actiononyandz ;; *) Actiononnomatch ;; ESAC | (Fall Ein Charakter ((#\a) Action-on-a) ((#\x) Aktion-auf-x) ((#\ y #\ z) Action-on-y-and-Z) (anders Action-on-No-Match)) |
Schleifen
Eine Schleife ist eine Abfolge von Aussagen, die einmal angegeben werden, die jedoch mehrmals nacheinander ausgeführt werden können. Der Code "im Inneren" der Schleife (der Karosserie der Schleife, unten gezeigt als xxx) wird für jede Sammlung von Elementen oder bis ein Zustand erfüllt oder bis zum Erfüllen oder einer bestimmten Erfüllung oder einmal befolgt werden oder einmal oder einmal unbegrenzt.
Im Funktionelle Programmierung Sprachen wie z. Haskell und Planen, Schleifen können durch Verwendung ausgedrückt werden Rekursion oder Iteration fester Punkt anstatt explizite Schleifenkonstrukte. Schwanzrekursion ist ein Sonderfall von Rekursion, der leicht in Iteration umgewandelt werden kann.
Count kontrollierte Schleifen
Die meisten Programmiersprachen haben Konstruktionen für die Wiederholung einer Schleife eine bestimmte Anzahl von Male. In den meisten Fällen kann das Zählen nach oben anstelle von nach oben gehen und es können andere Schritte als 1 verwendet werden.
Für i = 1 bis n | zum I: = 1 zu N tun Start xxx | xxx als nächstes i | Ende; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------- tun Sie i = 1, n | zum (I = 1; i <= n; ++ i) {xxx | xxx Ende do | }
In diesen Beispielen kann die Schleife, wenn n <1, einmal ausführen (mit Wert 1) oder gar nicht, je nach Programmiersprache.
In vielen Programmiersprachen können nur Ganzzahlen in einer zählenden Schleife zuverlässig verwendet werden. Schwimmpunktzahlen sind aufgrund von Hardwarebeschränkungen ungenau dargestellt, also eine Schleife wie z.
zum X: = 0,1 Schritt 0,1 zu 1.0 tun
Kann 9- oder 10 -mal wiederholt werden, abhängig von Rundfehlern und/oder der Hardware und/oder der Compiler -Version. Wenn die Erhöhung von x durch wiederholte Addition auftritt, können akkumulierte Rundungsfehler bedeuten, dass der Wert von x in jeder Iteration von der erwarteten Sequenz von 0,1, 0,2, 0,3, ..., 1,0 erheblich unterschiedlich sein kann.
Kontrollierte Schleifen
Die meisten Programmiersprachen haben Konstruktionen zum Wiederholen einer Schleife, bis sich einige Bedingungen ändert. Einige Variationen testen den Zustand zu Beginn der Schleife; Andere testen es am Ende. Wenn der Test am Anfang ist, kann der Körper vollständig übersprungen werden. Wenn es am Ende ist, wird der Körper immer mindestens einmal ausgeführt.
Machen während (test) | wiederholen xxx | xxx Loop | bis um Prüfung; ------------------------------------------------------------------------------------------------------------------------------------------------------ während (Test) {| tun xxx | xxx} | während (Prüfung);
A Kontrollpause ist eine Wertänderungserkennungsmethode, die innerhalb ordentlicher Schleifen verwendet wird, um die Verarbeitung für Wertegruppen auszulösen. Die Werte werden innerhalb der Schleife überwacht und eine Änderung wird den Programmfluss zum Handhabung des damit verbundenen Gruppenereignisses umleitet.
Tun Sie bis (End-of-Datei-Ende), wenn New-Zipcode <> aktuell-pipcode display_tally (aktuelleszipcode, zipCount) aktuell-ripcode = new-ipcode zipCount = 0 endif ZipCount ++ Loop
Sammlungssteuerschleifen
Mehrere Programmiersprachen (z. B.,, Ada, D, C ++ 11, Smalltalk, Php, Perl, Objekt Pascal, Java, C#, Matlab, Visual Basic, Rubin, Python, JavaScript, Forran 95 und später) haben spezielle Konstrukte, die eine implizite Schleife durch alle Elemente eines Arrays oder alle Mitglieder eines Satzes oder einer Sammlung ermöglichen.
Somecollection tun: [: Jede DeLement | xxx].
zum Artikel in Sammlung tun Start xxx Ende; für jeden (Element; MyCollection) {xxx} für jeden Somearray {xxx} für jeden ($ Somearray als $ k => $ v) {xxx} collection <string> coll; zum (String S: Coll) {} für jeden (Saite s in MyStringCollection) {xxx} somecollection | Foreach-object {$ _}
für alle (Index = zuerst: zuletzt: Schritt ...)
Scala hat Forexpressionen, die die sammelgesteuerte Schleifen verallgemeinern und auch andere Verwendungszwecke unterstützen, wie z. Asynchrone Programmierung. Haskell hat Doexpressionen und Verständnisse, die zusammen eine ähnliche Funktion wie Forexpressionen in Scala bieten.
Allgemeine Iteration
Allgemeine Iterationskonstrukte wie C's zum
Aussage und Common Lisp's tun
Form kann verwendet werden, um eine der oben genannten Arten von Schleifen und andere auszudrücken, z. B. über eine Reihe von Sammlungen parallel. Wenn ein spezifischeres Schleifenkonstrukt verwendet werden kann, wird es normalerweise gegenüber dem allgemeinen Iterationskonstrukt bevorzugt, da es häufig den Zweck des Ausdrucks klarer macht.
Unendliche Schleifen
Unendliche Schleifen werden verwendet, um ein Programmsegmentschleifen für immer oder bis eine außergewöhnliche Bedingung auftritt, z. B. ein Fehler. Zum Beispiel ein ereignisorientiertes Programm (wie a Server) Sollte für immer schaufeln, Ereignisse wie sie auftreten und nur dann anhalten, wenn der Prozess von einem Bediener gekündigt wird.
Unendliche Schleifen können mit anderen Kontrollflusskonstrukten implementiert werden. Am häufigsten ist es bei unstrukturiertem Programmieren, dass dies zurückspringt (GOTO), während bei strukturierter Programmierung dies eine unbestimmte Schleife (während Schleife) ist während (wahr) ...
. Einige Sprachen verfügen über spezielle Konstrukte für unendliche Schleifen, typischerweise, indem der Zustand aus einer unbestimmten Schleife weggelassen wird. Beispiele sind ADA (Schleife ... Endschleife
),[4] Forran (Tun ... Ende tun
), Gehen (zum { ... }
) und Ruby (Schleife tun ... Ende
).
Oft wird eine unendliche Schleife ungewollt durch einen Programmierfehler in einer konditionsgesteuerten Schleife erzeugt, wobei die Schleifenbedingung Variablen verwendet, die sich nie innerhalb der Schleife ändern.
Fortsetzung mit der nächsten Iteration
Manchmal besteht im Körper einer Schleife der Wunsch, den Rest des Schleifenkörpers zu überspringen und mit der nächsten Iteration der Schleife fortzusetzen. Einige Sprachen geben eine Aussage wie z. fortsetzen
(die meisten Sprachen), überspringen
,[5] oder nächste
(Perl und Ruby), was dies tun wird. Der Effekt besteht darin, den innersten Schleifenkörper vorzeitig zu beenden und dann mit der nächsten Iteration wie gewohnt wieder aufzunehmen. Wenn die Iteration die letzte in der Schleife ist, wird die gesamte Schleife frühzeitig beendet.
Stromeration wiederholen
Einige Sprachen, wie Perl[6] und Ruby,[7] haben eine Wiederholung
Aussage, die die aktuelle Iteration von Anfang an neu startet.
Schleifen neu starten
Ruby hat a wiederholen
Aussage, die die gesamte Schleife aus der ersten Iteration neu startet.[8]
Früher Ausstieg aus Schleifen
Bei der Verwendung einer zählungsgesteuerten Schleife, um eine Tabelle zu durchsuchen, ist es möglicherweise wünschenswert, die Suche einzustellen, sobald der erforderliche Element gefunden wurde. Einige Programmiersprachen geben eine Aussage wie z. Unterbrechung
(die meisten Sprachen), Ausgang
(Visuell grundlegend) oder letzte
(Perl), der die aktuelle Schleife sofort beenden und die Steuerung unmittelbar nach dieser Schleife in die Anweisung übertragen wird. Ein weiterer Begriff für frühe Loops ist anderthalb Schleifen.
Das folgende Beispiel wird in durchgeführt Ada was beides unterstützt Früher Ausstieg aus Schleifen und Schleifen mit Test in der Mitte. Beide Funktionen sind sehr ähnlich und der Vergleich beider Code -Snippets zeigt den Unterschied: Früher Ausgang muss mit einem kombiniert werden wenn Aussage während a Zustand in der Mitte ist ein in sich geschlossenes Konstrukt.
mit Ada.text Io; mit Ada.Integer Text Io; Verfahren Print_squares ist X : Ganze Zahl; Start Read_data : Schleife Ada.Ganze Zahl Text Io.Erhalten(X); Ausfahrt Read_data Wenn X = 0; Ada.Text Io.Stellen (X * X); Ada.Text Io.Neue Zeile; Ende Schleife Read_data; Ende Print_squares;
Python Unterstützt die bedingte Ausführung des Codes, je nachdem, ob eine Schleife früh beendet wurde (mit a Unterbrechung
Anweisung) oder nicht, indem Sie eine elende Klausel mit der Schleife verwenden. Zum Beispiel,
zum n in set_of_numbers: wenn isprime(n): drucken("Set enthält eine Primzahl") Unterbrechung anders: drucken("Set enthielt keine Primzahlen")
Das anders
Klausel im obigen Beispiel ist mit dem verknüpft zum
Aussage und nicht die innere wenn
Aussage. Beide Python zum
und während
Loops unterstützen eine solchen Klausel, die nur ausgeführt wird, wenn ein frühzeitiger Ausgang der Schleife nicht aufgetreten ist.
Einige Sprachen unterstützen Unterstützung aus verschachtelten Schleifen; In der Theorie werden diese Kreise mit mehreren Ebenen bezeichnet. Ein häufiges Gebrauchsbeispiel ist die Suche nach einer mehrdimensionalen Tabelle. Dies kann entweder über mehrstufige Pausen erfolgen (ausbrechen N Ebenen) wie bei Bash[9] und PHP,[10] oder über beschriftete Pausen (ausbrechen und beim gegebenen Etikett weitermachen), wie in Java und Perl.[11] Zu den Alternativen zu mehrstufigen Pausen gehören einzelne Pausen sowie eine staatliche Variable, die getestet wird, um eine andere Ebene auszubrechen. Ausnahmen, die auf dem Niveau gefangen werden, der ausgebrochen wird; Platzierung der verschachtelten Schleifen in einer Funktion und Verwendung der Rückkehr zur Beendigung der gesamten verschachtelten Schleife; Oder verwenden Sie ein Etikett und eine GOTO -Anweisung. C enthält keine mehrstufige Pause, und die übliche Alternative besteht darin, eine GOTO zu verwenden, um eine beschriftete Pause zu implementieren.[12] Python hat keine mehrstufige Pause oder weiter - dies wurde in vorgeschlagen Pep 3136und abgelehnt auf der Grundlage, dass die zusätzliche Komplexität die seltene legitime Verwendung nicht wert war.[13]
Der Begriff von Multi-Level-Pausen ist von einem Interesse an Interesse an Theoretische Informatik, weil es zu dem entsteht, was heute die genannt wird Kosaraju Hierarchie.[14] 1973 S. Rao Kosaraju raffinierte die Strukturierter Programm Theorem Indem es nachweist, dass es möglich ist, zusätzliche Variablen in strukturierter Programmierung hinzuzufügen, sind mehrstufige Pausen aus Schleifen zulässig.[15] Darüber hinaus hat Kosaraju bewiesen, dass eine strenge Programmenhierarchie vorhanden ist: für jede ganze Zahl nEs gibt ein Programm mit einem mehrstufigen Bruch der Tiefe n Das kann nicht als Programm mit mehrstufiger Tiefenbrüche weniger als programmiert werden n ohne zusätzliche Variablen einzuführen.[14]
Man kann auch Rückkehr
Aus einer Unterroutine, die die geschleifenden Aussagen ausführt, bricht sowohl aus der verschachtelten Schleife als auch aus der Unterroutine aus. Da sind andere Vorgeschlagene Kontrollstrukturen Für mehrere Pausen, diese werden jedoch im Allgemeinen stattdessen als Ausnahmen implementiert.
In seinem Lehrbuch von 2004, David Watt Verwendet Tennents Vorstellung von Sequenzer Erklären Sie die Ähnlichkeit zwischen mehrstufigen Pausen und Rückgabeberechnungen. Watt merkt an, dass eine Klasse von Sequenzern als als bekannt ist Fluchtsequenzer, definiert als "Sequenzer, der die Ausführung eines textuell einschließenden Befehls oder Verfahrens beendet", umfasst beide Pausen aus Schleifen (einschließlich Multi-Level-Pausen) und Rückgabeberichtungen. Wie häufig implementiert, können Rücksendesequenzer jedoch auch einen (Rückgabe-) Wert tragen, während der in zeitgenössische Sprachen implementierte Break -Sequenzer normalerweise nicht möglich ist.[16]
Schleifenvarianten und Invarianten
Schleifenvarianten und Schleifeninvarianten werden verwendet, um die Korrektheit von Schleifen auszudrücken.[17]
In praktischer Hinsicht ist eine Schleifenvariante ein ganzzahliger Ausdruck, der einen anfänglichen nicht negativen Wert hat. Der Wert der Variante muss während jeder Schleifen -Iteration abnehmen, darf jedoch während der korrekten Ausführung der Schleife niemals negativ werden. Schleifenvarianten werden verwendet, um zu garantieren, dass Schleifen enden.
Eine Schleifeninvariante ist eine Behauptung, die vor der ersten Schleifen -Iteration wahr sein muss und nach jeder Iteration wahr bleibt. Dies impliziert, dass, wenn eine Schleife korrekt endet, sowohl die Ausstiegsbedingung als auch die Schleifeninvariante erfüllt sind. Loop -Invarianten werden verwendet, um bestimmte Eigenschaften einer Schleife während aufeinanderfolgender Iterationen zu überwachen.
Einige Programmiersprachen, wie z. Eiffel Native Unterstützung für Schleifenvarianten und Invarianten enthalten. In anderen Fällen ist Support ein Add-On, wie das Java -ModellierungsspracheSpezifikation für Schleifenaussagen in Java.
Schleifenverminderung
Etwas Lispeln Dialekte bieten eine umfangreiche Sublanguage für die Beschreibung von Schleifen. Ein frühes Beispiel kann in Conversional LISP von gefunden werden Interisp. Common Lisp[18] Bietet ein Schleifenmakro, das eine solche Sublanguage implementiert.
Schleifensystemkreuzerferenztabelle
Programmiersprache | bedingt | Schleife | Früher Ausgang | Schleife Fortsetzung | Wiederholung | wiederholen | Korrektheitseinrichtungen | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Start | Mitte | Ende | zählen | Sammlung | Allgemeines | unendlich [1] | Variante | unveränderlich | |||||
Ada | Ja | Ja | Ja | Ja | Arrays | Nein | Ja | tief verschachtelt | Nein | ||||
Apl | Ja | Nein | Ja | Ja | Ja | Ja | Ja | tief verschachtelt [3] | Ja | Nein | Nein | ||
C | Ja | Nein | Ja | Nein [2] | Nein | Ja | Nein | tief verschachtelt [3] | tief verschachtelt [3] | Nein | |||
C ++ | Ja | Nein | Ja | Nein [2] | Ja [9] | Ja | Nein | tief verschachtelt [3] | tief verschachtelt [3] | Nein | |||
C# | Ja | Nein | Ja | Nein [2] | Ja | Ja | Nein | tief verschachtelt [3] | tief verschachtelt [3] | ||||
Cobol | Ja | Nein | Ja | Ja | Nein | Ja | Nein | tief verschachtelt [15] | tief verschachtelt [14] | Nein | |||
Common Lisp | Ja | Ja | Ja | Ja | Nur gebaut [16] | Ja | Ja | tief verschachtelt | Nein | ||||
D | Ja | Nein | Ja | Ja | Ja | Ja | Ja[14] | tief verschachtelt | tief verschachtelt | Nein | |||
Eiffel | Ja | Nein | Nein | Ja [10] | Ja | Ja | Nein | ein Level [10] | Nein | Nein | Nein [11] | Nur Ganzzahl [13] | Ja |
F# | Ja | Nein | Nein | Ja | Ja | Nein | Nein | Nein [6] | Nein | Nein | |||
Forran 77 | Ja | Nein | Nein | Ja | Nein | Nein | Nein | ein Level | Ja | ||||
Forran 90 | Ja | Nein | Nein | Ja | Nein | Nein | Ja | tief verschachtelt | Ja | ||||
Forran 95 und später | Ja | Nein | Nein | Ja | Arrays | Nein | Ja | tief verschachtelt | Ja | ||||
Haskell | Nein | Nein | Nein | Nein | Ja | Nein | Ja | Nein [6] | Nein | Nein | |||
Java | Ja | Nein | Ja | Nein [2] | Ja | Ja | Nein | tief verschachtelt | tief verschachtelt | Nein | nicht einheimisch [12] | nicht einheimisch [12] | |
JavaScript | Ja | Nein | Ja | Nein [2] | Ja | Ja | Nein | tief verschachtelt | tief verschachtelt | Nein | |||
Natürlich | Ja | Ja | Ja | Ja | Nein | Ja | Ja | Ja | Ja | Ja | Nein | ||
Ocaml | Ja | Nein | Nein | Ja | Arrays, Listen | Nein | Nein | Nein [6] | Nein | Nein | |||
Php | Ja | Nein | Ja | Nein [2] [5] | Ja [4] | Ja | Nein | tief verschachtelt | tief verschachtelt | Nein | |||
Perl | Ja | Nein | Ja | Nein [2] [5] | Ja | Ja | Nein | tief verschachtelt | tief verschachtelt | Ja | |||
Python | Ja | Nein | Nein | Nein [5] | Ja | Nein | Nein | tief verschachtelt [6] | tief verschachtelt [6] | Nein | |||
Rebol | Nein [7] | Ja | Ja | Ja | Ja | Nein [8] | Ja | ein Level [6] | Nein | Nein | |||
Rubin | Ja | Nein | Ja | Ja | Ja | Nein | Ja | tief verschachtelt [6] | tief verschachtelt [6] | Ja | Ja | ||
Standard ml | Ja | Nein | Nein | Nein | Arrays, Listen | Nein | Nein | Nein [6] | Nein | Nein | |||
Visual Basic .net | Ja | Nein | Ja | Ja | Ja | Nein | Ja | eine Stufe pro Art von Schleife | eine Stufe pro Art von Schleife | ||||
Power Shell | Ja | Nein | Ja | Nein [2] | Ja | Ja | Nein | ? | Ja |
- a
während (wahr)
Zählt für diesen Zweck nicht als unendliche Schleife, da es sich nicht um eine spezielle Sprachstruktur handelt. - a b c d e f g h C's
für (init; test; Inkrement)
Schleife ist ein allgemeines Schleifenkonstrukt, nicht speziell ein Zähler, obwohl es häufig dafür verwendet wird. - a b c In APL, C, C ++ und C# können tiefe Pausen durch die Verwendung von Etiketten und Gotos erreicht werden.
- a Iteration über Objekte war hinzugefügt in Php 5.
- a b c Eine Zählschleife kann simuliert werden, indem beispielsweise Python's über eine Inkrementierliste oder ein Generator Iteriert wird
Angebot()
. - a b c d e Tiefe Pausen können durch die Verwendung von Ausnahmebehandlung erreicht werden.
- a Es gibt kein besonderes Konstrukt, da die
während
Die Funktion kann dafür verwendet werden. - a Es gibt kein spezielles Konstrukt, aber Benutzer können allgemeine Schleifenfunktionen definieren.
- a Das C ++ 11 Standard stellte die vor Bereichsbasis für. In dem Stl, da ist ein
std :: for_each
Schablone Funktion, die auf STL iterieren kann Behälter und rufen Sie a Unary -Funktion Für jedes Element.[19] Die Funktionalität kann auch als konstruiert werden Makro auf diesen Behältern.[20] - a Die count-kontrollierte Schleife erfolgt durch Iteration über ein ganzzahliges Intervall; Frühe Ausstieg durch Einbeziehung einer zusätzlichen Bedingung für den Ausgang.
- a Eiffel unterstützt ein zurückhaltendes Wort
wiederholen
jedoch wird es in verwendet Ausnahmebehandlung, keine Schleifenkontrolle. - a Erfordert Java -Modellierungssprache (JML) Sprache der Verhaltensschnittstellenspezifikation.
- a Erfordert Schleifenvarianten für Ganzzahlen; Transfinite Varianten werden nicht unterstützt. [1]
- a D unterstützt unendliche Sammlungen und die Fähigkeit, diese Sammlungen zu iterieren. Dies erfordert kein spezielles Konstrukt.
- a Tiefe Pausen können mit Verwendung erreicht werden
GEHE ZU
und Verfahren. - a Common Lisp im Vorsprung vor dem Konzept des generischen Sammlungstyps.
Strukturierter nicht lokaler Kontrollfluss
Viele Programmiersprachen, insbesondere diejenigen, die dynamischere Programmierstile bevorzugen, bieten Konstrukte für Nicht-lokaler Kontrollfluss. Diese führen dazu, dass der Ausführungfluss aus einem bestimmten Kontext herausspringt und an einem vorgefertigten Punkt wieder aufgenommen wird. Bedingungen, Ausnahmen und Kontinuationen sind drei gemeinsame Arten von nicht-lokalen Kontrollkonstrukten; Es gibt auch exotische, wie z. Generatoren, Coroutinen und die Async Stichwort.
Bedingungen
Pl/i hat einige 22 Standardbedingungen (z. B. Zerodidiger subcriprange Endfile), die angehoben werden können und die durch: on abgefangen werden können: on Bedingung Aktion; Programmierer können auch ihre eigenen benannten Bedingungen definieren und verwenden.
Wie unstrukturiert, wennEs kann nur eine Aussage angegeben werden, sodass in vielen Fällen ein GOTO erforderlich ist, um zu entscheiden, wo der Kontrollfluss wieder aufgenommen wird.
Leider hatten einige Implementierungen einen erheblichen Aufwand sowohl in Raum als auch in der Zeit (insbesondere in Abonnements), so dass viele Programmierer versuchten, Bedingungen zu vermeiden.
Häufige Syntax -Beispiele:
AN Bedingung GEHE ZU Etikett
Ausnahmen
Moderne Sprachen haben ein spezielles strukturiertes Konstrukt für Ausnahmebehandlung GEHE ZU
oder (mehrstufig) bricht oder kehrt zurück. Zum Beispiel kann man in C ++ schreiben:
Versuchen { xxx1 // irgendwo hier xxx2 // benutze: '' 'throw' '' irgendwann; xxx3 } Fang (Someclass& Einige) { // Wert von Someclass fangen ActionForsomeClass } Fang (irgendwann& Noch eine ID) { // Wert von irgendeiner AnieTyp fangen actionForsometype } Fang (...) { // etwas fangen, was noch nicht gefangen wurde actionforanythingelse }
Beliebige Anzahl und Vielfalt von Fang
Klauseln können oben verwendet werden. Wenn es keine gibt Fang
Einen bestimmten Wurf
Steuern Sie die Perkolation durch Unterroutine -Anrufe und/oder verschachtelte Blöcke bis zu einer Übereinstimmung Fang
wird gefunden oder bis zum Ende des Hauptprogramms erreicht, und an diesem Punkt wird das Programm mit einer geeigneten Fehlermeldung gewaltsam gestoppt.
Über den Einfluss von C ++, Fang
Ist das Schlüsselwort reserviert, der für den Deklarieren eines Ausnahmebehandels für Muster in anderen Sprachen wie Java oder C#reserviert ist. Einige andere Sprachen wie ADA verwenden das Schlüsselwort Ausnahme
Um einen Ausnahmebehandler einzuführen und dann sogar ein anderes Schlüsselwort zu verwenden (Wenn
in ADA) für das Musteranpassung. Ein paar Sprachen wie Apfelkript Integrieren Sie Platzhalter in die Ausnahme -Handler -Syntax, um automatisch mehrere Informationen zu extrahieren, wenn die Ausnahme auftritt. Dieser Ansatz wird unten durch die veranschaulicht auf Fehler
Konstrukt aus AppleScript:
Versuchen einstellen meine Nummer zu meine Nummer / 0 an Error e Nummer n aus f zu t teilweise Ergebnis pr wenn ( e = "Kann nicht durch Null teilen" ) dann Dialog anzeigen "Das darfst du nicht tun" Ende Versuchen
David Watts 2004 -Lehrbuch analysiert auch die Ausnahmebehandlung im Rahmen der Sequenzer (in diesem Artikel im Abschnitt zu frühen Ausgängen aus Loops eingeführt). Watt merkt an, dass eine abnormale Situation, die im Allgemeinen mit arithmetischen Überläufen veranschaulicht wurde oder Input-Output Fehler wie nicht gefundene Dateien sind eine Art Fehler, der "in einer Programmeinheit auf niedriger Ebene erkannt wird, aber für die ein Handler in einer hochrangigen Programmeinheit natürlicher ist". Beispielsweise kann ein Programm mehrere Anrufe zum Lesedateien enthalten, aber die Aktion, die ausgeführt werden soll, wenn eine Datei nicht gefunden wird befindet sich im Systemcode auf niedrigem Niveau. Watts stellt weiter fest, dass die Einführung von Statusflags im Anrufer als strukturierte Programmierung von Einzelaussagen oder sogar (Multi-Exit-) Rückgabesequenzer zu einer Situation führt, in der "der Anwendungscode dazu neigt, durch Tests von Status-Flags" und durch Tests von Status-Flags "und durch Tests von Status-Flags zu werden" und "und durch Tests von Status-Flags" und "und" der Anwendungscode tendiert dazu neigt, durch Tests von Status-Flags "und" und "und tendenziell durch Tests von Status-Flags" und "und" und tendenziell durch Tests von Status-Flags "und" und Dass "der Programmierer möglicherweise nachsichtlich oder faul wegweist, um eine Statusflagge zu testen. Tatsächlich werden abnormale Situationen, die durch Statusflags dargestellt werden, standardmäßig ignoriert!" Watt merkt an, dass Ausnahmen im Gegensatz zu den Tests der Statusflags das Gegenteil haben Standardverhalten, was das Programm beendet, es sei denn, der Programmierer befasst sich explizit mit der Ausnahme in irgendeiner Weise, möglicherweise indem der explizite Code hinzugefügt wird, um ihn zu ignorieren. Basierend auf diesen Argumenten kommt Watt zu dem Schluss, dass Sprungsequenzer oder Escape -Sequenzer mit der oben diskutierten Semantik nicht so geeignet sind wie ein dedizierter Ausnahmeberechnung.[21]
In Objekt Pascal, D, Java, C#und Python a endlich
Klausel kann zum hinzugefügt werden Versuchen
konstruieren. Egal wie die Kontrolle das verlässt Versuchen
der Code im Inneren der endlich
Die Klausel wird garantiert ausgeführt. Dies ist nützlich, wenn Sie Code schreiben, das eine teure Ressource (z. B. eine geöffnete Datei oder eine Datenbankverbindung) aufgeben muss, wenn sie bearbeitet werden:
Datenfluss stm = Null; // C# Beispiel Versuchen { stm = Neu Datenfluss("logfile.txt", Filemode.Schaffen); Rückkehr Processstuff(stm); // kann eine Ausnahme auswerfen } endlich { wenn (stm ! = Null) stm.Nah dran(); }
Da dieses Muster ziemlich häufig ist, hat C# eine spezielle Syntax:
Verwendung (var stm = Neu Datenfluss("logfile.txt", Filemode.Schaffen)) { Rückkehr Processstuff(stm); // kann eine Ausnahme auswerfen }
Beim Verlassen des Verwendung
-Blocks garantiert der Compiler, dass die stm
Objekt wird effektiv freigesetzt Bindung Die Variable zum Dateistrom, während sie sich von den Nebenwirkungen der Initialisierung und Freigabe der Datei abstrahieren. Python mit
Aussage und Rubys Blockargument für Datei öffnen
werden an ähnliche Effekte verwendet.
Alle oben genannten Sprachen definieren Standardausnahmen und die Umstände, unter denen sie geworfen werden. Benutzer können eigene Ausnahmen veröffentlichen; Tatsächlich ermöglicht C ++ es Benutzern, fast jeden Typ zu werfen und zu fangen, einschließlich grundlegender Typen wie int
, während andere Sprachen wie Java nicht so zulässig sind.
Kontinuationen
Async
C# 5.0 stellte das async -Schlüsselwort für die Unterstützung vor asynchroner i/o in einem "direkten Stil".
Generatoren
GeneratorenErmöglichen yield
Stichwort (Ertragsbeschreibung). Wie das asynchrische Schlüsselwort unterstützt dies die Programmierung in einem "direkten Stil".
Coroutinen
Coroutinen sind Funktionen, die einander die Kontrolle liefern können - eine Form von kooperatives Multitasking ohne Fäden.
Coroutinen können als Bibliothek implementiert werden, wenn die Programmiersprache entweder Kontinuationen oder Generatoren bietet - daher ist die Unterscheidung zwischen Coroutinen und Generatoren in der Praxis ein technisches Detail.
Nicht-lokale Kontrollflusskreuzreferenz
Programmiersprache | Bedingungen | Ausnahmen | Generatoren/Coroutinen | Async |
---|---|---|---|---|
Ada | Nein | Ja | ? | ? |
C | Nein | Nein | Nein | Nein |
C ++ | Nein | Ja | Ja, durch Verwendung von Boost | ? |
C# | Nein | Ja | Ja | Ja |
Cobol | Ja | Ja | Nein | Nein |
Common Lisp | Ja | Nein | ? | ? |
D | Nein | Ja | Ja | ? |
Eiffel | Nein | Ja | ? | ? |
Erlang | Nein | Ja | Ja | ? |
F# | Nein | Ja | Ja | Ja |
gehen | Nein | Ja | Ja | ? |
Haskell | Nein | Ja | Ja | Nein |
Java | Nein | Ja | Nein | Nein |
JavaScript | ? | Ja | Ja | Ja |
Ziel c | Nein | Ja | Nein | ? |
Php | Nein | Ja | Ja | ? |
Pl/i | Ja | Nein | Nein | Nein |
Python | Nein | Ja | Ja | Ja[22] |
Rebol | Ja | Ja | Nein | ? |
Rubin | Nein | Ja | Ja | per Erweiterung[23] |
Rost | Nein | Ja | Experimental- [24][25] | Ja[26] |
Scala | Nein | Ja | über experimentelle Erweiterung[27] | über experimentelle Erweiterung |
Tcl | über Spuren | Ja | Ja | Via Event Loop |
Visual Basic .net | Ja | Ja | Nein | ? |
Power Shell | Nein | Ja | Nein | ? |
Vorgeschlagene Kontrollstrukturen
In einer Parodie DataMation Artikel[28] 1973 schlug R. Lawrence Clark vor, dass die GOTO -Erklärung durch die ersetzt werden könnte KOMME AUS Aussage und liefert einige unterhaltsame Beispiele. Com von einem wurde in einem implementiert Esoterische Programmiersprache genannt Intercal.
Donald Knuth's 1974 Artikel "Strukturiertes Programmieren mit Go to Statements",[29] identifiziert zwei Situationen, die nicht durch die oben aufgeführten Kontrollstrukturen abgedeckt wurden, und gaben Beispiele für Kontrollstrukturen, die diese Situationen bewältigen konnten. Trotz ihres Nutzens haben diese Konstrukte ihren Weg in die Mainstream -Programmiersprachen noch nicht gefunden.
Schleife mit Test in der Mitte
Das Folgende wurde von vorgeschlagen von Dahl 1972:[30]
Schleife Schleife xxx1 read (char); während Prüfung; während nicht Atendoffile; xxx2 write (char); wiederholen; wiederholen;
Wenn xxx1 ist weggelassen, wir bekommen eine Schleife mit dem Test oben (ein traditionelles während Schleife). Wenn xxx2 wird weggelassen, wir bekommen eine Schleife mit dem Test unten, gleichwertig zu a tu während Schleife in vielen Sprachen. Wenn während ist weggelassen, wir bekommen eine unendliche Schleife. Die Konstruktion hier kann als als betrachtet werden tun Schleifen Sie mit der Mitte an. Daher kann diese einzelne Konstruktion in den meisten Programmiersprachen mehrere Konstruktionen ersetzen.
Sprachen, denen dieses Konstrukt fehlt, emulieren es im Allgemeinen mit einer äquivalenten Infinite-Loop-mit-Break-Idiom:
während (true) {xxx1 wenn (nicht Prüfung) Unterbrechung xxx2}
Eine mögliche Variante besteht darin, mehr als eine zuzulassen während Prüfung; innerhalb der Schleife, aber die Verwendung von beenden Sie, wenn (Siehe nächster Abschnitt) scheint diesen Fall besser abzudecken.
Im Ada, das obige Schleifenkonstrukt (Schleife-während-wiederholen) kann unter Verwendung einer Standard -Infinite -Schleife dargestellt werden (Schleife - Endschleife) das hat eine beenden Sie wann Klausel in der Mitte (nicht zu verwechseln mit dem beenden Sie, wenn Anweisung im folgenden Abschnitt).
mit Ada.text_io; mit Ada.Ineger_text_io; Verfahren Print_squares ist X : Ganze Zahl; Start Read_data : Schleife Ada.INTEGER_TEXT_IO.Erhalten(X); Ausfahrt Read_data Wenn X = 0; Ada.Text Io.Stellen (X * X); Ada.Text Io.Neue Zeile; Ende Schleife Read_data; Ende Print_squares;
Benennung einer Schleife (wie wie Read_data in diesem Beispiel) ist optional, ermöglicht es jedoch zu, die äußere Schleife mehrerer verschachtelter Schleifen zu verlassen.
Mehrere frühe Ausstieg/Ausstieg aus verschachtelten Schleifen
Dies wurde von vorgeschlagen von Zahn 1974.[31] Eine modifizierte Version wird hier vorgestellt.
beenden Sie, wenn Eventa oder Eventb oder EventC; xxx Ausgänge Eventa: Actiona EventB: ActionB EventC: ActionC Endexit;
beenden Sie, wenn wird verwendet, um die Ereignisse anzugeben, die innerhalb des Inneren auftreten können xxxIhr Auftreten wird durch die Verwendung des Namens des Ereignisses als Erklärung angezeigt. Wenn ein Ereignis auftritt, wird die entsprechende Aktion durchgeführt und dann die Pässe kurz danach kontrolliert Endexit. Diese Konstruktion bietet eine sehr klare Trennung zwischen der Bestimmung, dass eine Situation gilt, und der für diese Situation ergriffenen Maßnahmen.
beenden Sie, wenn ist konzeptionell ähnlich wie Ausnahmebehandlungund Ausnahmen oder ähnliche Konstrukte werden in vielen Sprachen zu diesem Zweck verwendet.
Das folgende einfache Beispiel beinhaltet die Suche nach einer zweidimensionalen Tabelle nach einem bestimmten Element.
beenden Sie, wenn gefunden oder fehlen; zum I: = 1 zu N tun zum J: = 1 zu M tun wenn Tabelle [i, j] = Ziel dann gefunden; fehlen; Ausgänge gefunden: print ("Artikel ist in der Tabelle"); fehlend: drucken ("Artikel ist nicht in der Tabelle"); Endexit;
Sicherheit
Eine Möglichkeit, eine Software anzugreifen, besteht darin, den Durchführung eines Programms umzuleiten. Eine Vielzahl von Integrität des Kontrollflusss Techniken, einschließlich Stapel Kanaren, Pufferüberlaufschutz, Schattenstapel und vtable Die Zeigerüberprüfung wird verwendet, um gegen diese Angriffe zu verteidigen.[32][33][34]
Siehe auch
- Zweig (Informatik)
- Kontrollstrahlanalyse
- Kontrollflusdiagramm
- Kontroll-Flow-Diagramm
- Steuerungstabelle
- Coroutine
- Zyklomatische Komplexität
- Drakon-Chart
- Flussdiagramm
- GEHE ZU
- Jeroo, hilft, Kontrollstrukturen zu lernen
- Hauptschleife
- Rekursion
- Planung (Computer)
- Spaghetti -Code
- Strukturierte Programmierung
- Subroutine
- Schaltanweisung, verändert den Steuerfluss bedingt
Verweise
- ^ Böhm, Jacopini. "Durchflussdiagramme, Turing -Maschinen und Sprachen mit nur zwei Formationsregeln" Comm. ACM, 9 (5): 366-371, Mai 1966.
- ^ a b Roberts, E. [1995] "Schleifenausgänge und strukturierte Programmierung: Wiedereröffnung der Debatte, ”ACM Sigcse Bulletin, (27) 1: 268–272.
- ^ David Anthony Watt; William Findlay (2004). Programmiersprache Designkonzepte. John Wiley & Sons. p. 228. ISBN 978-0-470-85320-7.
- ^ ADA -Programmierung: Kontrolle: Endlose Schleife
- ^ "Was ist eine Schleife und wie können wir sie benutzen?". Abgerufen 2020-05-25.
- ^ "Redo - perldoc.perl.org". perldoc.perl.org. Abgerufen 2020-09-25.
- ^ "Control_expressions - Dokumentation für Ruby 2.4.0". Docs.Ruby-Lang.org. Abgerufen 2020-09-25.
- ^ "Control_expressions - Dokumentation für Ruby 2.3.0". Docs.Ruby-Lang.org. Abgerufen 2020-09-25.
- ^ Advanced Bash Scripting Guide: 11.3. Schleifenkontrolle
- ^ PHP -Handbuch: "Unterbrechung"
- ^ PERLDOC: letzte
- ^ comp.lang.c FAQ -Liste · "Frage 20.20b"
- ^ [Python-3000] Ankündigung von PEP 3136, Guido van Rossum
- ^ a b Kozen, Dexter (2008). "Der Böhm -Jacopini -Theorem ist falsch, aussagekräftig". Mathematik der Programmkonstruktion (PDF). Vorlesungsnotizen in Informatik. Vol. 5133. S. 177–192. Citeseerx 10.1.1.218.9241. doi:10.1007/978-3-540-70594-9_11. ISBN 978-3-540-70593-2.
- ^ Kosaraju, S. Rao. "Analyse strukturierter Programme", Proc. Fünfter jährlicher ACM -Sirup. Theorie des Computers (Mai 1973), 240-252; auch in J. Computer and System Sciences, 9, 3 (Dezember 1974). zitiert von Donald Knuth (1974). "Strukturiertes Programmieren mit Go to Aussagen". Computerumfragen. 6 (4): 261–301. Citeseerx 10.1.1.103.6084. doi:10.1145/356635.356640. S2CID 207630080.
- ^ David Anthony Watt; William Findlay (2004). Programmiersprache Designkonzepte. John Wiley & Sons. S. 215–221. ISBN 978-0-470-85320-7.
- ^ Meyer, Bertrand (1991). Eiffel: Die Sprache. Prentice Hall. S. 129–131.
- ^ "Common Lisp Loop Makro".
- ^ für jeden. Sgi.com. Abgerufen am 2010-11-09.
- ^ Kapitel 1. Boost.foreach. Boost-sandbox.sourceforge.net (2009-12-19). Abgerufen am 2010-11-09.
- ^ David Anthony Watt; William Findlay (2004). Programmiersprache Designkonzepte. John Wiley & Sons. S. 221–222. ISBN 978-0-470-85320-7.
- ^ "Asyncio - Asynchron I/O - Python 3.10.2 Dokumentation".
- ^ "Socketry/Async". GitHub. 25. Februar 2022.
- ^ "Generatoren - das rost instabile Buch".
- ^ "Corona - Rost".
- ^ "Erste Schritte - Asynchrones Programmieren in Rost".
- ^ http://storm-enroute.com/coroutines/
- ^ Wir wissen nicht, wohin wir gehen sollen, wenn wir nicht wissen, woher wir kommen. Diese (Parodie-) sprachliche Innovation erfüllt alle Erwartungen. Archiviert 2018-07-16 bei der Wayback -Maschine Von R. Lawrence Clark* aus DataMation, Dezember 1973
- ^ Knuth, Donald E. "Strukturierte Programmierung mit Aussagen" GO TO ZUT ERSICHTEN " ACM Computing -Umfragen 6 (4): 261-301, Dezember 1974.
- ^ Dahl & Dijkstra & Hoare, "Structured Programming" Academic Press, 1972.
- ^ Zahn, C. T. "Eine Kontrollanweisung für natürliche Top-Down-strukturierte Programmierung", präsentiert auf dem Symposium über Programmiersprachen, Paris, 1974.
- ^ Zahler, Mathias; Kuznetsov, Volodymyr. "Über Unterschiede zwischen den Eigenschaften von CFI, CPS und CPI". nebelwelt.net. Abgerufen 2016-06-01.
- ^ "Die Entdeckung von Adobe Flash -Fehler führt zu einer neuen Methode zur Minderung der Angriffsminderung". Dunkle Lesung. 10. November 2015. Abgerufen 2016-06-01.
- ^ Endspiel. "Endgame, um bei Black Hat USA 2016 zu präsentieren". www.prnewswire.com. Abgerufen 2016-06-01.
Weitere Lektüre
- Hoare, C. A. R. "Partition: Algorithmus 63", "Quicksort: Algorithmus 64" und "Finden Sie: Algorithmus 65." Comm. ACM 4, 321-322, 1961.
Externe Links
- Medien im Zusammenhang mit dem Kontrollfluss bei Wikimedia Commons
- Gehen Sie zu einer schädlichen Aussage als schädlich
- Ein sprachlicher Beitrag der Goto-ohne-Programmierung
- "Strukturiertes Programmieren mit Go to Aussagen" (PDF). Archiviert von das Original (PDF) am 2009-08-24. (2,88 MB)
- "IBM 704 Handbuch" (PDF). (31,4 MB)