lernen:goto
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | lernen:goto [2022-05-22 16:12] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== goto Spaghetti : Unstrukturiertes Programmieren ====== | ||
+ | < | ||
+ | Die Qualität des Quelltextes steht im umgekehrten Verhältnis | ||
+ | zur verwendeten Zahl von Sprungbefehlen. | ||
+ | --- Edsger Wybe Dijkstra</ | ||
+ | |||
+ | |||
+ | ===== Aufgabe ===== | ||
+ | Verstehst du den folgenden Quelltext? | ||
+ | |||
+ | <code cpp> | ||
+ | if (n == 1) goto stop; | ||
+ | if (n % 2 == 0) goto gerade; | ||
+ | ungerade: | ||
+ | n = 3 * n + 1; | ||
+ | if ( n == 1) goto stop; | ||
+ | gerade: | ||
+ | n = n / 2; | ||
+ | if (n == 1) goto stop; | ||
+ | if (n % 2 == 0) goto gerade; | ||
+ | goto ungerade; | ||
+ | stop: | ||
+ | </ | ||
+ | Veranschauliche ihn mit einem Programmablaufplan (Flussdiagramm, | ||
+ | Vereinfache den Algorithmus, | ||
+ | Baue den Quelltext so um, dass er in einem Struktogramm (DIN 66261) darstellbar ist. | ||
+ | Codiere das Ergebnis wieder in C++. | ||
+ | Ziehe Schlussfolgerungen. | ||
+ | |||
+ | ===== Lösung ===== | ||
+ | ==== Programmablaufplan ==== | ||
+ | Ein Flussdiagramm (Programmablaufplan) | ||
+ | ist eine (die einzige?) Möglichkeit, | ||
+ | den Programmablauf zu verdeutlichen. | ||
+ | |||
+ | {{gotopap1.png| Flussdiagramm nach DIN 66001. }} | ||
+ | |||
+ | ==== Umbau ==== | ||
+ | Der Steuerfluss ist unnötig kompliziert. | ||
+ | Besonders fallen die beiden aufeinander folgenden Tests ins Auge. | ||
+ | Die Tests im unteren Bildteil lassen sich entfernen, | ||
+ | wenn nach dem Halbieren zum Start zurückgegangen wird. | ||
+ | |||
+ | {{gotopap2.png| Vereinfachter Steuerfluss. }} | ||
+ | |||
+ | Mit Strichlinie markiert ist die nächste Vereinfachung. | ||
+ | Der Rücksprung zum Start nach dem Verdreifachen | ||
+ | spart eine weitere Verzweigung. | ||
+ | So entsteht eine dritte, strukturierte Version, | ||
+ | die aus einer abweisenden Schleife und einer Verzweigung besteht. | ||
+ | |||
+ | {{gotopap3.png| Strukturiertes Programm. }} | ||
+ | |||
+ | ==== Struktogramm ==== | ||
+ | In einem Nassi-Shneiderman-Diagramm (Struktogramm) | ||
+ | treten Schleifen und Verzweigungen deutlicher hervor | ||
+ | als im Programmablaufplan. | ||
+ | |||
+ | {{gotonsd.png| Struktogramm nach DIN 66261. }} | ||
+ | |||
+ | ==== Vereinfachter Quelltext ==== | ||
+ | Der entstehende Quelltext ist nur halb so lang und einfacher zu verstehen. | ||
+ | |||
+ | <code cpp> | ||
+ | while (n != 1) | ||
+ | { | ||
+ | if (n % 2 == 0) | ||
+ | n = n / 2; | ||
+ | else | ||
+ | n = 3 * n + 1; | ||
+ | } | ||
+ | </ | ||
+ | ===== Wertung ===== | ||
+ | Programme mit vielen Sprungbefehlen sind schwer verständlich | ||
+ | und damit fehleranfällig. | ||
+ | Solche Quelltext umzubauen ist auch nicht immer einfach. | ||
+ | Vielmehr sollte man beim Algorithmenentwurf darauf achten, | ||
+ | nicht nur mit "wenn ... dann ..." zu formulieren, | ||
+ | sondern wiederholte Anweisungen mit den Worten | ||
+ | " | ||
+ | |||
+ | |||
+ | > Solange wie n noch nicht bei 1 angekommen ist, | ||
+ | >> | ||
+ | >> | ||
+ | |||
+ | Dann kann Spaghetti-Code gar nicht erst entstehen. | ||
+ | Um aufrichtig zu sein, | ||
+ | es ist ein unfaires, zu stark vereinfachendes Beispiel. | ||
+ | Es gibt komplexe Situationen, | ||
+ | Allerdings sind diese Situationen sehr selten. | ||
+ | |||
+ | Spaghetti gehören auf den Teller, nicht in den Quelltext. | ||
+ | Pasta! | ||
+ | |||
+ | ===== weiterführende Literatur ===== | ||
+ | - Edsger W. Dijkstra: Go To Statement Considered Harmful. CACM 11, No. 3 (March 1968) 147-148. | ||
+ | - Donald E. Knuth: Structured Programming with goto. (1974). | ||
+ | - Steve McConnell: Code Complete. Microsoft Press. (1993) 347-359. | ||
+ | |||
+ | |||
+ | |||