Strukturierte Programmierung – Wikipedia

Programmierparadigma zur Verbesserung von Klarheit, Qualität und Entwicklungszeit durch Verwendung von Kontrollstrukturen

Strukturierte Programmierung ist ein Programmierparadigma, das darauf abzielt, die Klarheit, Qualität und Entwicklungszeit eines Computerprogramms zu verbessern, indem die strukturierten Kontrollflusskonstrukte Auswahl (wenn / dann / sonst) und Wiederholung (während und für), Blockstrukturen und Unterprogramme.

Es entstand in den späten 1950er Jahren mit dem Erscheinen der Programmiersprachen ALGOL 58 und ALGOL 60,[1] mit letzterem einschließlich Unterstützung für Blockstrukturen. Zu den Faktoren, die zu seiner Popularität und weit verbreiteten Akzeptanz zunächst in der Wissenschaft und später bei Praktikern beitragen, gehört die Entdeckung des heutigen Satzes über strukturierte Programme im Jahr 1966.[2] und die Veröffentlichung des einflussreichen offenen Briefes “Go To Statement Considered Harmful” im Jahr 1968 durch den niederländischen Informatiker Edsger W. Dijkstra, der den Begriff “strukturierte Programmierung” prägte.

Strukturierte Programmierung wird am häufigsten mit Abweichungen verwendet, die in bestimmten Fällen klarere Programme ermöglichen, z. B. wenn eine Ausnahmebehandlung durchgeführt werden muss.

Elemente[edit]

Kontrollstrukturen[edit]

Nach dem Satz des strukturierten Programms bestehen alle Programme aus Kontrollstrukturen:

  • “Reihenfolge”; geordnete Anweisungen oder Unterprogramme, die nacheinander ausgeführt werden.
  • “Auswahl”; Je nach Status des Programms wird eine oder mehrere Anweisungen ausgeführt. Dies wird normalerweise mit Schlüsselwörtern wie ausgedrückt if..then..else..endif. Die bedingte Anweisung sollte mindestens eine wahre Bedingung haben und jede Bedingung sollte einen Austrittspunkt bei max.
  • “Wiederholung”; Eine Anweisung oder ein Block wird ausgeführt, bis das Programm einen bestimmten Status erreicht oder Operationen auf jedes Element einer Sammlung angewendet wurden. Dies wird normalerweise mit Schlüsselwörtern wie ausgedrückt while, repeat, for oder do..until. Oft wird empfohlen, dass jede Schleife nur einen Einstiegspunkt hat (und in der ursprünglichen Strukturprogrammierung auch nur einen Austrittspunkt, und einige Sprachen erzwingen dies).
  • “Rekursion”; Eine Anweisung wird ausgeführt, indem sie sich wiederholt aufruft, bis die Beendigungsbedingungen erfüllt sind. Rekursive Schleifen sind zwar in der Praxis iterativen Schleifen ähnlich, können jedoch rechnerisch effizienter sein und werden als kaskadierender Stapel unterschiedlich implementiert.

Unterprogramme[edit]

Unterprogramme; Aufrufbare Einheiten wie Prozeduren, Funktionen, Methoden oder Unterprogramme werden verwendet, um zu ermöglichen, dass eine Sequenz durch eine einzelne Anweisung referenziert wird.

Blöcke[edit]

Blöcke werden verwendet, um zu ermöglichen, dass Gruppen von Anweisungen so behandelt werden, als wären sie eine Anweisung. Blockstrukturiert Sprachen haben eine Syntax zum formellen Einschließen von Strukturen, z. B. eine if-Anweisung in Klammern mit if..fi wie in ALGOL 68 oder einem Codeabschnitt in Klammern von BEGIN..END, wie in PL / I und Pascal, Leerzeicheneinrückung wie in Python – oder die geschweiften Klammern {...} von C und vielen späteren Sprachen.

Strukturierte Programmiersprachen[edit]

Es ist möglich, strukturierte Programmierung in jeder Programmiersprache durchzuführen, obwohl es vorzuziehen ist, so etwas wie eine prozedurale Programmiersprache zu verwenden. Einige der Sprachen, die ursprünglich für die strukturierte Programmierung verwendet wurden, umfassen: ALGOL, Pascal, PL / I und Ada, aber die meisten neuen prozeduralen Programmiersprachen seit dieser Zeit enthalten Funktionen zur Förderung der strukturierten Programmierung und manchmal absichtlich ausgelassene Funktionen – insbesondere GOTO – in einem Bemühungen, die unstrukturierte Programmierung zu erschweren.
Strukturierte Programmierung (manchmal auch als modulare Programmierung bekannt[citation needed]) erzwingt eine logische Struktur des zu schreibenden Programms, um es effizienter und einfacher zu verstehen und zu ändern.

Geschichte[edit]

Theoretische Grundlage[edit]

Der Satz des strukturierten Programms liefert die theoretische Grundlage der strukturierten Programmierung. Es heißt, dass drei Möglichkeiten zum Kombinieren von Programmen – Sequenzierung, Auswahl und Iteration – ausreichen, um eine berechenbare Funktion auszudrücken. Diese Beobachtung stammt nicht aus der strukturierten Programmierbewegung; Diese Strukturen reichen aus, um den Befehlszyklus einer Zentraleinheit sowie den Betrieb einer Turingmaschine zu beschreiben. Daher führt ein Prozessor immer ein “strukturiertes Programm” in diesem Sinne aus, selbst wenn die Anweisungen, die er aus dem Speicher liest, nicht Teil eines strukturierten Programms sind. Die Autoren schreiben das Ergebnis jedoch normalerweise einem Artikel von Böhm und Jacopini aus dem Jahr 1966 zu, möglicherweise weil Dijkstra diesen Artikel selbst zitiert hat.[4] Der Satz über strukturierte Programme befasst sich nicht mit dem Schreiben und Analysieren eines nützlich strukturierten Programms. Diese Probleme wurden in den späten 1960er und frühen 1970er Jahren mit wichtigen Beiträgen von Dijkstra, Robert W. Floyd, Tony Hoare, Ole-Johan Dahl und David Gries angegangen.

Debatte[edit]

PJ Plauger, ein früher Anwender der strukturierten Programmierung, beschrieb seine Reaktion auf den Satz des strukturierten Programms:

Wir Konvertiten schwenkten diese interessante Neuigkeit unter die Nase der nicht rekonstruierten Assembler-Programmierer, die immer wieder verdrehte Logik hervorbrachten und sagten: “Ich wette, das kann ich nicht strukturieren.” Weder der Beweis von Böhm und Jacopini noch unsere wiederholten Erfolge beim Schreiben von strukturiertem Code brachten sie einen Tag früher herum, als sie bereit waren, sich selbst zu überzeugen.[5]

Donald Knuth akzeptierte das Prinzip, dass Programme unter Berücksichtigung der Beweisbarkeit geschrieben werden müssen, aber er war anderer Meinung (und immer noch anderer Meinung)[citation needed]) mit der Abschaffung der GOTO-Erklärung. In seiner Arbeit von 1974 “Strukturierte Programmierung mit Gehe zu Anweisungen”,[6] Er gab Beispiele, bei denen er glaubte, dass ein direkter Sprung zu klarerem und effizienterem Code führt, ohne die Beweisbarkeit zu beeinträchtigen. Knuth schlug eine lockerere strukturelle Einschränkung vor: Es sollte möglich sein, ein Flussdiagramm eines Programms mit allen Vorwärtszweigen links, allen Rückwärtszweigen rechts und ohne sich kreuzenden Zweigen zu zeichnen. Viele derjenigen, die sich mit Compilern und Graphentheorie auskennen, haben sich dafür ausgesprochen, nur reduzierbare Flussgraphen zuzulassen[when defined as?].[who?]

Theoretiker der strukturierten Programmierung gewannen in den 1970er Jahren einen wichtigen Verbündeten, nachdem der IBM-Forscher Harlan Mills seine Interpretation der Theorie der strukturierten Programmierung auf die Entwicklung eines Indexierungssystems für anwendete Die New York Times Forschungsdatei. Das Projekt war ein großer technischer Erfolg, und Manager anderer Unternehmen führten es zur Unterstützung der Einführung einer strukturierten Programmierung an, obwohl Dijkstra kritisierte, wie sich Mills ‘Interpretation von der veröffentlichten Arbeit unterschied.[citation needed]

Noch 1987 war es möglich, die Frage der strukturierten Programmierung in einem Informatikjournal zu stellen. Frank Rubin tat dies in diesem Jahr mit einem offenen Brief mit dem Titel “GOTO als schädlich” als schädlich “.[7] Es folgten zahlreiche Einwände, darunter eine Antwort von Dijkstra, die sowohl Rubin als auch die Zugeständnisse anderer Schriftsteller bei der Beantwortung scharf kritisierte.

Ergebnis[edit]

Bis zum Ende des 20. Jahrhunderts waren fast alle Informatiker davon überzeugt, dass es nützlich ist, die Konzepte der strukturierten Programmierung zu lernen und anzuwenden. Hochrangige Programmiersprachen, denen ursprünglich Programmierstrukturen fehlten, wie FORTRAN, COBOL und BASIC, haben sie jetzt.

Häufige Abweichungen[edit]

Während goto inzwischen weitgehend durch die strukturierten Konstrukte Auswahl (wenn / dann / sonst) und Wiederholung (während und für) ersetzt wurde, sind nur wenige Sprachen rein strukturiert. Die häufigste Abweichung, die in vielen Sprachen auftritt, ist die Verwendung einer return-Anweisung zum vorzeitigen Verlassen eines Unterprogramms. Dies führt zu mehreren Austrittspunkten anstelle des einzelnen Austrittspunkts, der für die strukturierte Programmierung erforderlich ist. Es gibt andere Konstruktionen, um Fälle zu behandeln, die bei der rein strukturierten Programmierung umständlich sind.

Vorzeitiger Ausstieg[edit]

Die häufigste Abweichung von der strukturierten Programmierung ist das frühzeitige Verlassen einer Funktion oder Schleife. Auf der Ebene der Funktionen ist dies a return Erklärung. Auf der Ebene der Schleifen ist dies a break Anweisung (Schleife beenden) oder continue Anweisung (Beenden Sie die aktuelle Iteration, fahren Sie mit der nächsten Iteration fort). Bei der strukturierten Programmierung können diese durch Hinzufügen zusätzlicher Zweige oder Tests repliziert werden. Bei Rückgaben aus verschachteltem Code kann dies jedoch zu einer erheblichen Komplexität führen. C ist ein frühes und prominentes Beispiel für diese Konstrukte. Einige neuere Sprachen haben auch “beschriftete Unterbrechungen”, die das Ausbrechen von mehr als nur der innersten Schleife ermöglichen. Ausnahmen ermöglichen auch einen vorzeitigen Ausstieg, haben jedoch weitere Konsequenzen und werden daher im Folgenden behandelt.

Mehrere Exits können aus verschiedenen Gründen auftreten, meistens entweder, weil das Unterprogramm keine Arbeit mehr zu erledigen hat (wenn ein Wert zurückgegeben wird, hat es die Berechnung abgeschlossen) oder wenn “außergewöhnliche” Umstände aufgetreten sind, die verhindern, dass es fortgesetzt wird, und daher erforderlich sind Ausnahmebehandlung.

Das häufigste Problem beim vorzeitigen Beenden besteht darin, dass Bereinigungs- oder Abschlussanweisungen nicht ausgeführt werden. Beispielsweise wird der zugewiesene Speicher nicht freigegeben oder offene Dateien werden nicht geschlossen, was zu Speicher- oder Ressourcenlecks führt. Diese müssen an jeder Rückgabestelle durchgeführt werden, die spröde ist und leicht zu Fehlern führen kann. Beispielsweise könnte in einer späteren Entwicklung eine return-Anweisung von einem Entwickler übersehen werden, und eine Aktion, die am Ende einer Unterroutine ausgeführt werden sollte (z. B. eine Trace-Anweisung), wird möglicherweise nicht in allen Fällen ausgeführt. Sprachen ohne return-Anweisung wie Standard Pascal und Seed7 haben dieses Problem nicht.

Die meisten modernen Sprachen bieten Unterstützung auf Sprachebene, um solche Lecks zu verhindern. Siehe ausführliche Diskussion unter Ressourcenmanagement. Am häufigsten erfolgt dies über einen Abwicklungsschutz, der sicherstellt, dass bestimmte Codes garantiert ausgeführt werden, wenn die Ausführung einen Block verlässt. Dies ist eine strukturierte Alternative zu einem Bereinigungsblock und einem goto. Dies ist am häufigsten bekannt als try...finally, und als Teil der Ausnahmebehandlung betrachtet. Bei mehreren return einleitende Aussagen try...finally, ohne Ausnahmen könnte seltsam aussehen. Es gibt verschiedene Techniken, um das Ressourcenmanagement zu kapseln. Ein alternativer Ansatz, der hauptsächlich in C ++ zu finden ist, ist Resource Acquisition Is Initialization, bei dem das normale Abwickeln des Stapels (variable Freigabe) beim Beenden der Funktion verwendet wird, um Destruktoren für lokale Variablen aufzurufen, um die Freigabe von Ressourcen aufzuheben.

Kent Beck, Martin Fowler und Co-Autoren haben in ihren Refactoring-Büchern argumentiert, dass verschachtelte Bedingungen möglicherweise schwerer zu verstehen sind als eine bestimmte Art von flacherer Struktur, wenn mehrere Ausgänge verwendet werden, die durch Schutzklauseln vorhergesagt werden. In ihrem Buch von 2009 heißt es rundweg: “Ein Austrittspunkt ist wirklich keine nützliche Regel. Klarheit ist das Schlüsselprinzip: Wenn die Methode mit einem Austrittspunkt klarer ist, verwenden Sie einen Austrittspunkt, andernfalls nicht.” Sie bieten eine Kochbuchlösung zum Umwandeln einer Funktion, die nur aus verschachtelten Bedingungen besteht, in eine Folge von geschützten Rückgabeanweisungen (oder Wurfanweisungen), gefolgt von einem einzelnen unbewachten Block, der den Code für den allgemeinen Fall enthalten soll, während die geschützten Anweisungen sind soll mit den weniger häufigen (oder mit Fehlern) umgehen.[9]Herb Sutter und Andrei Alexandrescu argumentieren in ihrem C ++ – Tippbuch von 2004 auch, dass der Single-Exit-Punkt eine veraltete Anforderung ist.[10]

In seinem Lehrbuch von 2004 schreibt David Watt, dass “Kontrollflüsse mit einem Eingang und mehreren Ausgängen oft wünschenswert sind”. Unter Verwendung von Tennents Framework-Konzept des Sequenzierers beschreibt Watt einheitlich die Kontrollflusskonstrukte, die in modernen Programmiersprachen zu finden sind, und versucht zu erklären, warum bestimmte Arten von Sequenzern im Kontext von Kontrollflüssen mit mehreren Ausgängen anderen vorzuziehen sind. Watt schreibt, dass uneingeschränkte Gotos (Sprungsequenzierer) schlecht sind, weil das Ziel des Sprunges für den Leser eines Programms nicht selbsterklärend ist, bis der Leser das tatsächliche Etikett oder die Adresse findet und untersucht, die das Ziel des Sprunges ist. Im Gegensatz dazu argumentiert Watt, dass die konzeptionelle Absicht eines Return-Sequenzers aus seinem eigenen Kontext klar hervorgeht, ohne dass sein Ziel untersucht werden muss. Watt schreibt, dass eine Klasse von Sequenzern bekannt als Escape-Sequenzer, definiert als “Sequenzer, der die Ausführung eines textumschließenden Befehls oder einer Prozedur beendet”, umfasst sowohl Unterbrechungen von Schleifen (einschließlich mehrstufiger Unterbrechungen) als auch return-Anweisungen. Watt merkt auch an, dass Sprungsequenzer (gotos) in Sprachen wie C, in denen das Ziel ein innerhalb des lokalen Blocks oder ein umfassender äußerer Block sein muss, etwas eingeschränkt waren, diese Einschränkung allein jedoch nicht ausreicht, um die Absicht von gotos in C self zu machen -beschreibend und so können sie immer noch “Spaghetti-Code” produzieren. Watt untersucht auch, wie sich Ausnahme-Sequenzer von Flucht- und Sprung-Sequenzern unterscheiden. Dies wird im nächsten Abschnitt dieses Artikels erläutert.[11]

Im Gegensatz dazu schrieb Bertrand Meyer in seinem Lehrbuch 2009, dass Anweisungen wie break und continue “sind nur die alten goto im Schafspelz “und dringend von ihrer Verwendung abgeraten.[12]

Ausnahmebehandlung[edit]

Basierend auf dem Codierungsfehler der Ariane 501-Katastrophe argumentiert der Softwareentwickler Jim Bonang, dass alle von einer Funktion ausgelösten Ausnahmen das Single-Exit-Paradigma verletzen, und schlägt vor, alle prozeduralen Ausnahmen zu verbieten. In der C ++ – Syntax erfolgt dies, indem alle Funktionssignaturen als deklariert werden noexcept (seit C ++ 11) oder throw().[13] Bonang schlägt vor, dass alle Single-Exit-konformen C ++ wie folgt geschrieben werden sollten:

bool MyCheck1() throw() {
  bool success = false;
  try {
    // Do something that may throw exceptions.
    if (!MyCheck2()) {
      throw SomeInternalException();
    }
    // Other code similar to the above.
    success = true;
  } catch (...) {
    // All exceptions caught and logged.
  }
  return success;
}

Peter Ritchie merkt auch an, dass im Prinzip sogar eine einzige throw kurz vor dem return in einer Funktion stellt eine Verletzung des Single-Exit-Prinzips dar, argumentiert jedoch, dass Dijkstras Regeln in einer Zeit geschrieben wurden, bevor die Ausnahmebehandlung zu einem Paradigma in Programmiersprachen wurde, und schlägt daher vor, zusätzlich zu einem einzelnen Rückgabepunkt eine beliebige Anzahl von Wurfpunkten zuzulassen . Er stellt fest, dass Lösungen, die Ausnahmen umschließen, um einen Single-Exit zu erstellen, eine höhere Verschachtelungstiefe aufweisen und daher schwieriger zu verstehen sind, und beschuldigt sogar diejenigen, die vorschlagen, solche Lösungen auf Programmiersprachen anzuwenden, die Ausnahmen des Frachtkultdenkens unterstützen .[14]

David Watt analysiert auch die Ausnahmebehandlung im Rahmen von Sequenzern (in diesem Artikel im vorherigen Abschnitt zu frühen Exits vorgestellt). Watt stellt fest, dass eine abnormale Situation (im Allgemeinen veranschaulicht durch arithmetische Überläufe oder Eingabe- / Ausgabefehler wie Datei nicht gefunden) eine Art ist Fehler, dass “in einer Low-Level-Programmeinheit erkannt wird, aber [for which] Ein Handler befindet sich natürlicher in einer übergeordneten Programmeinheit. “Ein Programm kann beispielsweise mehrere Aufrufe zum Lesen von Dateien enthalten. Die auszuführende Aktion, wenn eine Datei nicht gefunden wird, hängt jedoch von der Bedeutung (dem Zweck) der Datei in ab Eine Frage an das Programm und damit eine Handhabungsroutine für diese abnormale Situation kann nicht im Systemcode auf niedriger Ebene gefunden werden. Watts stellt ferner fest, dass das Einführen von Statusflags-Tests im Aufrufer als strukturierte Single-Exit-Programmierung oder sogar (Multi-Exit-) Return-Sequenzer Dies würde dazu führen, dass “der Anwendungscode durch Tests von Statusflags unübersichtlich wird” und “der Programmierer das Testen eines Statusflags möglicherweise vergesslich oder träge unterlässt. In der Tat werden abnormale Situationen, die durch Statusflags dargestellt werden, standardmäßig ignoriert! “Er stellt fest, dass Ausnahmen im Gegensatz zum Testen von Statusflags das entgegengesetzte Standardverhalten aufweisen und dazu führen, dass das Programm beendet wird, es sei denn, der Programmierer behandelt die Ausnahme möglicherweise explizit auf irgendeine Weise Durch Hinzufügen von Code, um ihn absichtlich zu ignorieren. Basierend auf diesen Argumenten kommt Watt zu dem Schluss, dass Sprungsequenzierer oder Escape-Sequenzer (im vorherigen Abschnitt beschrieben) nicht so geeignet sind wie ein dedizierter Ausnahmesequenzer mit der oben diskutierten Semantik.[15]

Das Lehrbuch von Louden und Lambert betont, dass sich die Ausnahmebehandlung von strukturierten Programmierkonstrukten wie unterscheidet while Schleifen, weil die Übertragung der Kontrolle “an einem anderen Punkt im Programm eingerichtet ist als an dem Punkt, an dem die eigentliche Übertragung stattfindet. An dem Punkt, an dem die Übertragung tatsächlich stattfindet, gibt es möglicherweise keinen syntaktischen Hinweis darauf, dass die Kontrolle tatsächlich übertragen wird.”[16] Der Informatikprofessor Arvind Kumar Bansal merkt auch an, dass in Sprachen, die Ausnahmebehandlung implementieren, sogar Kontrollstrukturen wie for, die die Single-Exit-Eigenschaft in Abwesenheit von Ausnahmen haben, haben sie nicht mehr in Gegenwart von Ausnahmen, da eine Ausnahme einen vorzeitigen Exit in irgendeinem Teil der Kontrollstruktur verursachen kann; zum Beispiel wenn init() löst eine Ausnahme aus for (init(); check(); increm()), dann ist der übliche Austrittspunkt nach check () nicht erreicht.[17] Westley Weimer und George Necula zitierten mehrere frühere Studien anderer (1999-2004) und ihre eigenen Ergebnisse und schrieben, dass ein bedeutendes Problem mit Ausnahmen darin besteht, dass sie “versteckte Kontrollflusspfade schaffen, über die Programmierer nur schwer nachdenken können”.[18]::8:27

Die Notwendigkeit, Code auf Single-Exit-Punkte zu beschränken, tritt in einigen modernen Programmierumgebungen auf, die sich auf paralleles Rechnen konzentrieren, wie z. B. OpenMP. Die verschiedenen parallelen Konstrukte von OpenMP mögen parallel doLassen Sie keine vorzeitigen Austritte von innen nach außen des parallelen Konstrukts zu. Diese Einschränkung umfasst alle Arten von Ausgängen von break zu C ++ – Ausnahmen, aber alle diese sind innerhalb des parallelen Konstrukts zulässig, wenn sich das Sprungziel auch darin befindet.[19]

Mehrfacheintrag[edit]

Seltener erlauben Unterprogramme mehrere Eintrag. Dies ist am häufigsten nur Re-Eintrag in eine Coroutine (oder Generator / Semicoroutine), in der ein Unterprogramm die Kontrolle (und möglicherweise einen Wert) liefert, aber dann dort fortgesetzt werden kann, wo es aufgehört hat. Es gibt eine Reihe gängiger Anwendungen dieser Programmierung, insbesondere für Streams (insbesondere Eingabe / Ausgabe), Zustandsautomaten und Parallelität. Unter dem Gesichtspunkt der Codeausführung ist das Nachgeben einer Coroutine näher an der strukturierten Programmierung als das Zurückgeben von einer Unterroutine, da das Unterprogramm nicht tatsächlich beendet wurde und beim erneuten Aufruf fortgesetzt wird – es ist kein vorzeitiger Exit. Coroutinen bedeuten jedoch, dass mehrere Unterprogramme einen Ausführungsstatus haben – und nicht einen einzelnen Aufrufstapel von Unterroutinen – und somit eine andere Form der Komplexität einführen.

Es ist sehr selten, dass Unterprogramme die Eingabe einer beliebigen Position im Unterprogramm ermöglichen, da in diesem Fall der Programmstatus (z. B. variable Werte) nicht initialisiert oder mehrdeutig ist und dies einem goto sehr ähnlich ist.

Zustandsautomaten[edit]

Einige Programme, insbesondere Parser und Kommunikationsprotokolle, haben eine Reihe von Zuständen, die auf eine Weise aufeinander folgen, die sich nicht leicht auf die Grundstrukturen reduzieren lässt, und einige Programmierer implementieren die Zustandsänderungen mit einem Sprung in den neuen Zustand. Diese Art der Statusumschaltung wird häufig im Linux-Kernel verwendet.[citation needed]

Es ist jedoch möglich, diese Systeme zu strukturieren, indem jede Zustandsänderung zu einem eigenen Unterprogramm gemacht wird und eine Variable verwendet wird, um den aktiven Zustand anzuzeigen (siehe Trampolin). Alternativ können diese über Coroutinen implementiert werden, die auf das Trampolin verzichten.

Siehe auch[edit]

Verweise[edit]

Zitate[edit]

  1. ^ Clark, Leslie B. Wilson, Robert G.; Robert, Clark (2000). Vergleichende Programmiersprachen (3. Aufl.). Harlow, England: Addison-Wesley. p. 20. ISBN 9780201710120. Archiviert vom Original am 26. November 2015. Abgerufen 25. November 2015.
  2. ^ Böhm, Corrado; Giuseppe Jacopini (Mai 1966). “Flussdiagramme, Turingmaschinen und Sprachen mit nur zwei Formationsregeln” (PDF). Mitteilungen der ACM. 9 (5): 366–371. CiteSeerX 10.1.1.119.9119. doi:10.1145 / 355592.365646. S2CID 10236439. Archiviert (PDF) vom Original am 23.09.2015.
  3. ^ Dijkstra, EW (März 1968). “Briefe an den Herausgeber: Zur Erklärung gehen, die als schädlich angesehen wird”. Mitteilungen der ACM. 11 (3): 147–148. doi:10.1145 / 362929.362947. ISSN 0001-0782. S2CID 17469809.
  4. ^ Plauger, PJ (12. Februar 1993). Zweckmäßiges Programmieren, Aufsätze zum Software-Design (1 ed.). Prentice-Hall. p. 25. ISBN 978-0-13-721374-0.
  5. ^ Donald Knuth – Strukturierte Programmierung mit go to Anweisungen Archiviert 23.10.2013 an der Wayback-Maschine
  6. ^ Frank Rubin (März 1987). “”“”GOTO als schädlich eingestuft “als schädlich eingestuft” (PDF). Mitteilungen der ACM. 30 (3): 195–196. doi:10.1145 / 214748.315722. S2CID 6853038. Archiviert von das Original (PDF) am 20.03.2009.
  7. ^ Jay Fields; Shane Harvie; Martin Fowler; Kent Beck (2009). Refactoring: Ruby Edition. Pearson Ausbildung. S. 274–279. ISBN 978-0-321-60350-0.
  8. ^ Herb Sutter; Andrei Alexandrescu (2004). C ++ – Codierungsstandards: 101 Regeln, Richtlinien und Best Practices. Pearson Ausbildung. ISBN 978-0-13-265442-5. “Beispiel 4: Einzeleintrag, Einzelausgang (” SESE “). In der Vergangenheit haben einige Codierungsstandards verlangt, dass jede Funktion genau einen Ausgang hat, was eine Rückgabeanweisung bedeutet. Eine solche Anforderung ist in Sprachen, die Ausnahmen und Destruktoren unterstützen, in denen Funktionen überholt sind haben normalerweise zahlreiche implizite Ausgänge. “)
  9. ^ David Anthony Watt; William Findlay (2004). Designkonzepte für Programmiersprachen. John Wiley & Sons. S. 215–221. ISBN 978-0-470-85320-7.
  10. ^ Bertrand Meyer (2009). Touch of Class: Lernen, mit Objekten und Verträgen gut zu programmieren. Springer Science & Business Media. p. 189. ISBN 978-3-540-92144-8.
  11. ^ “PragPub April 2012 – Die pragmatische Verteidigung – Das pragmatische Bücherregal”. pragprog.com. Archiviert vom Original am 10. Juli 2017. Abgerufen 6. Mai 2018.
  12. ^ “Single-Entry, Single-Exit, sollte es in objektorientierten Sprachen noch anwendbar sein? – Peter Ritchies MVP-Blog”. Archiviert vom Original am 14.11.2012. Abgerufen 2014-07-15.
  13. ^ David Anthony Watt; William Findlay (2004). Designkonzepte für Programmiersprachen. John Wiley & Sons. S. 221–222. ISBN 978-0-470-85320-7.
  14. ^ Kenneth C. Louden; Kenneth A. Lambert (2011). Programmiersprachen: Prinzipien und Praktiken (3. Aufl.). Lernen einbinden. p. 423. ISBN 978-1-111-52941-3.
  15. ^ Arvind Kumar Bansal (2013). Einführung in Programmiersprachen. CRC Drücken Sie. p. 135. ISBN 978-1-4665-6514-2.
  16. ^ Weimer, W & Necula, GC (2008). “Außergewöhnliche Situationen und Programmzuverlässigkeit” (PDF). ACM-Transaktionen zu Programmiersprachen und -systemen. 30 (2). Archiviert (PDF) vom Original am 23.09.2015.
  17. ^ Rohit Chandra (2001). Parallele Programmierung in OpenMP. Morgan Kaufmann. p. 45. ISBN 978-1-55860-671-5.

Quellen[edit]

Externe Links[edit]

  • BPStruct – Ein Werkzeug zur Strukturierung gleichzeitiger Systeme (Programme, Prozessmodelle)
  • J. Darlinton; M. Ghanem; HW To (1993), “Structured Parallel Programming”, In Programmiermodellen für massiv parallele Computer. IEEE Computer Society Press. 1993: 160–169, CiteSeerX 10.1.1.37.4610