Kontrollstrukturen -Entscheidungen, Abfragen und Fallunterscheidungen Informatik für Elektrotechnik und Informationstechnik Benedict Reuschling [email protected] Hochschule Darmstadt Fachbereich Informatik WS 2013/14 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Motivation Bisher sind alle unsere Programme sequentiell, d.h. Zeile für Zeile nacheinander abgearbeitet worden. Kontrollstrukturen dienen dazu, den Programmfluss so zu manipulieren, so dass an einer anderen Stelle im Programm mit der Ausführung fortgesetzt wird. Über Entscheidungen und Abfragen lassen sich zur Laufzeit bestimmte Bedingungen prüfen und dazugehörige Aktionen realisieren. Es ist damit also nicht mehr länger gewährleistet, dass das Programm jede Programmzeile erreicht und abarbeitet. Auf der anderen Seite werden die Programme dadurch flexibler und der Programmierer kann auf die verschiedensten Eingaben und Situationen reagieren (robuster Code). Durch die Kenntnis von Boolescher Logik und deren Kombinationen lassen sich alle möglichen Fälle zu einer Bedingung mit entsprechenden Handlungsanweisungen ausstatten. 2 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen if-Abfragen Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 3 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen if-Abfragen Entscheidungen definieren Eine Entscheidung wird in ihrer einfachsten Form in C++ folgendermassen verwendet: if (Bedingung) Anweisung; Nur dann, wenn die Bedingung in Klammern den booleschen Wert true ergibt, wird die Anweisung ausgeführt, sonst nicht. Man kann auch sagen, dass die Bedingung wahr oder falsch ist bzw. die Abfrage zutrifft oder nicht. 4 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen if-Abfragen Mehrere Anweisungen bei Entscheidungen ausführen Für den Fall, dass mehrere Anweisungen nach der erfolgreichen Prüfung der Bedingung ausgeführt werden sollen, so müssen diese in einem Block eingeschlossen sein. if (Bedingung) { Anweisung1; Anweisung2; AnweisungN; } Andernfalls kann es zu ungewünschten Nebeneffekten kommen: 1 2 3 if ( Bedingung ) Anweisung1 ; Anweisung2 ; Der Compiler wird beim Fehlen der geschweiften Klammern davon ausgehen, dass nur Anweisung1 zu der Abfrage gehört (die Einrückungen spielen keine Rolle für ihn). In diesem Fall wird Anweisung2 in Zeile 3 immer ausgeführt werden, egal, ob die Bedingung zutrifft oder nicht. 5 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen if-Abfragen Fallstrick bei der Verwendung von Semikolon Die if-Anweisung selbst benötigt kein Semikolon am Ende. Wird doch ein Semikolon nach der Bedingung eingefügt, so wird der Compiler das nicht als Fehler melden und das Programm übersetzen. Vorsicht mit dem Semikolon: if (Bedingung); Anweisung; In diesem Fall wertet der Compiler das Semikolon als das Ende der if-Anweisung. Die nachfolgende Anweisung wird auf jeden Fall ausgeführt, ganz egal ob die Bedingung zutrifft oder nicht. 6 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Bedingungen definieren Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 7 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Bedingungen definieren Bedingungen mit Vergleichsoperatoren definieren Die Bedingung in der if-Abfrage kann ein beliebiger Ausdruck sein, der entweder einen boolschen Wahrheitswert (true/false) oder nicht-Null ergibt. Das bedeutet, dass der Ausdruck if (expression) die gleiche Bedeutung hat wie if (expression != 0). Die folgenden Vergleichsoperatoren können verwendet werden: Operator == != > >= < <= Erläuterung liefert true, wenn beide Operanden gleich sind ergibt true, falls beide Operatoren ungleich sind ist true, sollte der linke Operand grösser als der rechte sein wie oben, nur wird ebenfalls auf Gleichheit geprüft true, wenn der linke Operand kleiner ist als der rechte wie oben, nur wird ebenfalls auf Gleichheit geprüft Beispiel x == 2, für x = 2; x != 1 x > y x >= y x < y x <= y 8 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Bedingungen definieren Beispiel zu Vergleichsoperatoren Hier wird die Verwendung des Vergleichsoperators <= gezeigt, um das Alter abzufragen und basierend auf der Eingabe einen anderen Wert zurückzugeben. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # include < iostream > using namespace std ; int main () { int alter , returnwert = 0; cout << " Bitte geben Sie ihr Alter in Jahren ein : " ; cin >> alter ; if ( alter <= 17) returnwert = 1; if ( alter == 100) returnwert = -1; } return returnwert ; Beachten Sie besonders den Unterschied zwischen dem Vergleich in Zeile 11 (==) und der Zuweisung in Zeile 12 mit nur einem =. Der Compiler akzeptiert auch Zuweisungen in der Bedingung einer if-Abfrage, dies ist aber selten das, was man haben möchte! 9 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Bedingungen definieren Vergleichen von char und string Zeichenketten und Strings lassen sich folgendermassen vergleichen. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # include < iostream > # include < string > using namespace std ; int main () { char eingabezeichen ; string eingabestring ; cout << " Das Fragezeichen eingeben , um Hilfe zu erhalten : " ; cin >> eingabezeichen ; if ( eingabezeichen == '? ') cout << " Hilfe noch nicht implementiert " ; cout << " Geben Sie ' Exit ' ein , um das Programm zu beenden : " ; cin >> eingabestring ; if ( eingabestring == " Exit " ) cout << " Programm wird beendet ! " ; } return 0; 10 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 11 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else else-Abschnitte Sollte die Bedingung einer if-Abfrage nicht zutreffen, kann ein alternativer Pfad eingeschlagen werden. Dieser wird immer dann ausgeführt, wenn die Bedingung nicht zutrifft und stellt dadurch eine Alternative dar, womit dann ``Wenn irgendetwas, dann x sonst y'' Verzweigungen im Programm ermöglicht werden. Die Syntax dazu lautet allgemein: Einzelne Anweisung ausführen: 1 2 3 4 if ( Bedingung ) Anweisung ; else Anweisung ; Mehrere Anweisungen ausführen: 1 2 3 4 5 6 if ( Bedingung ) { Anweisungen ; } else { Anweisungen ; } Natürlich lassen sich diese beiden Arten auch kombinieren, so dass bei einem else-Abschnitt nur eine Anweisung stehen kann, während die if-Abfrage mehrere Befehle ausführt, welche in geschweifte Klammern eingeschlossen sind und umgekehrt. 12 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Hörsaalübung Schreiben Sie ein Programm, dass den Benutzer nach seinem Alter fragt. Ist der Benutzer mindestens 18 Jahre alt, so soll eine Begrüssungsmeldung ausgegeben werden. Falls das Alter noch nicht erreicht wurde, soll eine Meldung den Anwender darauf hinweisen, dass das Programm erst mit 18 Jahren benutzt werden darf. Verwenden Sie einen geeigneten Vergleichsoperator in einem if else-Konstrukt und definieren Sie geeignete Variablentypen. 13 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Eine mögliche Lösung zur Hörsaalübung 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # include < iostream > # include < string > using namespace std ; int main () { unsigned int alter ; string nachricht ; cout << " Bitte geben Sie ihr Alter ein : " ; cin >> alter ; if ( alter >= 18) nachricht = " Willkommen !\ n " ; else nachricht = " Sie sind leider noch nicht alt genug !\ n " ; } cout << nachricht ; return 0; 14 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Der Operator zur bedingten Bewertung Es gibt einen speziellen Operator der eine verkürzte Schreibweise zur bedingten Bewertung ermöglicht. Die allgemeine Syntax lautet: Ausdruck ? Ausdruck_wahr : Ausdruck_falsch 1 2 3 4 int zahl ; cout << " Bitte geben Sie eine Zahl ein : " ; cin >> zahl ; cout << zahl << " ist " << ( zahl %2 == 0 ? " eine " : " keine " ) << " gerade Zahl !"; Bei der Verwendung dieses Operators ist Vorsicht geboten, denn der Code der dadurch entsteht, kann schnell unleserlich werden. Benutzen Sie stattdessen das if else-Konstrukt, wenn Sie die Übersicht verlieren. 15 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Verschachtelung von if else Es lassen sich auch mehrere if Konstrukte ineinander mit den dazugehörigen else-Abschnitten verschachteln. 1 2 3 4 5 6 7 if ( x < 100) { if (x == 50) { ... } else { ... } } Es muss immer klar geregelt sein, zu welchem if ein else gehört. Daher gilt die Regel, dass ein else immer zum unmittelbar vorherigen if gehört, wobei die Blockstruktur zu beachten ist. 1 2 3 4 5 if ( n > 0) if (a > b) z = a; else z = b; 1 2 3 4 5 6 if ( n > 0) { if ( a > b ) z = a; } else z = b; 16 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen ``Wenn dann sonst''-Abfragen mit else Die else if Bedingung Es lassen sich mehrere Bedingungen nacheinander abprüfen, indem das else if (Bedingung)-Konstrukt verwendet wird. 1 2 3 4 5 6 7 if ( x < 100) { ... } else if (y > 0) { ... } else { // in allen anderen Faellen } In diesem Fall lassen sich mehrere Bedingungen nacheinander abprüfen, die der Reihe nach ausgewertet werden. Falls keine dieser Bedingungen zutrifft, kann optional ein letztes else die übrigen Fälle abhandeln. 17 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 18 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Prüfen mehrerer Bedingungen auf einmal In der if-Bedingung können nicht nur eine, sondern beliebig viele Bedingungen geprüft werden. Da hier alle Aussagen entweder true oder false ergeben, entstehen verschiedene Kombinationen von Wahrheitswerten, die sich Mithilfe von Booleschen Funktionen miteinander verknüpfen lassen. So wird gewährleistet, dass alle möglichen Ergebnisse dieser Ausdrücke auch entsprechend abgearbeitet werden. Aus diesem Grund ist es wichtig, Boolesche Grundfunktionen zu kennen, um die richtige Verknüpfungsart in der if-Bedingung zu wählen. 19 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Logische Verknüpfungen Da wir nur boolesche Werte mit true und false betrachten, lassen sich sogenannte Wahrheitstabellen für deren Kombinationen miteinander aufstellen. Durch eine Wahrheitstabelle wird eine logische Verknüpfung mit mehreren Eingangssignalen zu einem (oder mehreren) Ausgangssignalen definiert. Durch die darin enthaltenen logischen Zusammenhänge zwischen Ein- und Ausgangssignalen erhält man die Gesetzmäÿigkeiten dieser Verknüpfung. Allgemein lautet die Syntax für mehrere logische Verknüpfungen: (Bedingung1 Logische_Verknüpfung Bedingung2) Welche verschiedenen Verknüpfungstypen und Kombinationsmöglichkeiten es gibt wollen wir uns nun ansehen. 20 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die OR-Verknüpfung Wenn mindestens einer der beiden Ausdrücke true ist, dann ergibt auch der Zielwert true und es handelt sich um eine OR (Oder) Verknüpfung, die in C++ mit || definiert wird. false || false = false 21 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die OR-Verknüpfung Wenn mindestens einer der beiden Ausdrücke true ist, dann ergibt auch der Zielwert true und es handelt sich um eine OR (Oder) Verknüpfung, die in C++ mit || definiert wird. false || false = false false || true = true 21 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die OR-Verknüpfung Wenn mindestens einer der beiden Ausdrücke true ist, dann ergibt auch der Zielwert true und es handelt sich um eine OR (Oder) Verknüpfung, die in C++ mit || definiert wird. false || false = false false || true = true true || false = true 21 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die OR-Verknüpfung Wenn mindestens einer der beiden Ausdrücke true ist, dann ergibt auch der Zielwert true und es handelt sich um eine OR (Oder) Verknüpfung, die in C++ mit || definiert wird. false || false = false false || true = true true || false = true true || true = true 21 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Beispiel zur Oder-Verknüpfung In einem vorherigen Beispiel hatten wir bemerkt, dass es einen Unterschied macht, ob ein Zeichen in Gross- oder in Kleinbuchstaben eingegeben und anschliessend den Vergleich angestellt wird. Wir wollen in diesem Beispiel dafür sorgen, dass sowohl 'x' als auch 'X' erkannt und in den entsprechenden Pfad verzweigt wird. Hierzu eignet sich die Oder-Verknüpfung: 1 2 3 4 5 6 7 char eingabe ; cout << " Bitte druecken Sie X zum beenden : " ; cin >> eingabe ; if ( eingabe == 'X ' || eingabe == 'x ') cout << " Programm wird beendet !\ n " ; else cout << " Programm wird fortgesetzt ...\ n " ; Zeile 4 kann so gelesen werden: Wenn die Variable eingabe den Wert 'X' oder den Wert 'x' hat, dann ist die if-Bedingung erfüllt (true). Generell erlaubt die Oder-Verknüpfung mehr Zustände, die true ergeben. Es genügt, wenn nur einer von mehreren mit oder verknüpften Ausdrücken true ist, um die ganze Aussage mit true zu bewerten. 22 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die AND-Verknüpfung Bei der AND (Und) Verknüpfung ist der Ausgangswert nur dann true, falls alle Eingänge den Wert true besitzen. Mit && werden die einzelnen Bedingungen im Quellcode verknüpft. false && false = false 23 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die AND-Verknüpfung Bei der AND (Und) Verknüpfung ist der Ausgangswert nur dann true, falls alle Eingänge den Wert true besitzen. Mit && werden die einzelnen Bedingungen im Quellcode verknüpft. false && false = false false && true = false 23 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die AND-Verknüpfung Bei der AND (Und) Verknüpfung ist der Ausgangswert nur dann true, falls alle Eingänge den Wert true besitzen. Mit && werden die einzelnen Bedingungen im Quellcode verknüpft. false && false = false false && true = false true && false = false 23 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Die AND-Verknüpfung Bei der AND (Und) Verknüpfung ist der Ausgangswert nur dann true, falls alle Eingänge den Wert true besitzen. Mit && werden die einzelnen Bedingungen im Quellcode verknüpft. false && false = false false && true = false true && false = false true && true = true 23 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Entscheidungen und Abfragen Mehrere Bedingungen prüfen mit booleschen Funktionen Beispiel zur Und-Verknüpfung In diesem Beispiel wird eine Bereichsüberprüfung für die Eingabe vorgenommen. Durch eine untere und obere Grenze wird der Wertebereich festgelegt. Somit müssen alle eingegebenen Werte sowohl grösser als der untere, als auch kleiner als der obere Bereich sein. 1 2 3 4 5 6 7 unsigned int zahl ; cout << " Bitte eine ganze Zahl zwischen 1 und 100 eingeben : " ; cin >> zahl ; if ( zahl >= 1 && zahl <= 100) cout << " Die Zahl befindet sich im Wertebereich ! " ; else cout << " Die Zahl ist ausserhalb des Wertebereichs . " ; Die Und Verknüpfung ist restriktiver, weil diese nur den Wahrheitswert true ergibt, wenn alle Bedingungen zutreffen, was nicht oft der Fall ist. Sobald auch nur eine davon mit false ausgewertet wird, kann die Gesamtbedingung nicht mehr true werden. 24 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 25 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Motivation Oftmals müssen in einem Programm Eingabewerte auf verschiedene Zielwerte geprüft werden. Ein typisches Beispiel ist ein Menü das verschiedene Funktionalitäten hinter Zahlen bereitstellt: 1) Neues Spiel 2) Spiel speichern 3) Spiel laden 4) Einstellungen 5) Spiel beenden Eingabe: Die Aufgabe ist nun, herauszubekommen, welche Zahl der Benutzer ausgewählt hat und entsprechend darauf zu reagieren. Es kann zwar ein grosses Konstrukt mit mehreren if else-Anweisungen diese Aufgabe lösen, allerdings wird dieses mit der Zeit unübersichtlich, je grösser das Menü wird. Für diese Art von Fallunterscheidungen existiert in vielen Programmiersprachen ein eigenes Konstrukt. 26 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Fallunterscheidung mit switch Um mehrere mögliche Ergebnisse mit einem eigenen Pfad abzudecken, eignet sich das switch case-Statement. In der allgemeinen Form hat es folgenden Aufbau: switch (Ausdruck) { case const1: Anweisung(en)1; break; case const2: Anweisung(en)2; break; default: Anweisung(en); break; } Der Ausdruck wird evaluiert und abhängig von dessen Wert wird in den entsprechenden case-Abschnitt verzweigt. Mit break wird dieser Zweig beendet, es ist also die letzte Anweisung und springt dann aus dem switch-Konstrukt. Für den Fall, dass keiner der Pfade auf den Ausdruck zutrifft, kann ein optionaler default-Pfad alle übrigen Fälle abhandeln. 27 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Beispiel zum switch case 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > using namespace std ; int main () { char menuewahl ; cout << " 1) Vorspeise " << endl ; cout << " 2) Hauptgang " << endl ; cout << " 3) Nachspeise " << endl ; cout << " 4) Keinen Appetit " << endl ; cin >> menuewahl ; switch ( menuewahl ) { case 1: cout << " Als Vorspeise gibt es ... " ; break ; case 2: cout << " Der Hauptgang beinhaltet ... " ; break ; case 3: cout << " Zum Dessert servieren wir ... " ; break ; default : cout << " Dann vielleicht morgen ... " ; break ; } return 0; } 28 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Hinweise zum switch-Statement Die Konstanten in den case-Abschnitten müssen nicht fortlaufend aufgelistet werden, sondern können eine beliebige Reihenfolge haben. 1 2 3 4 5 6 switch ( zahl ) { case 17: cout << " Siebzehn " ; break ; case 4: cout << " Vier " ; break ; } Es ist jedoch übersichtlicher, diese geordnet der Reihe nach aufzulisten. Achtung: In den case-Marken dürfen nur Konstanten und keine Variablen benutzt werden. Der folgende Code wird deshalb vom Compiler mit einer Fehlermeldung in Zeile 3 quittiert: 1 2 3 4 5 int x = 2; switch ( zahl ) { case x /2: cout << " x /2 " ; break ; } 29 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Fallunterscheidungen Das switch-Statement Gezieltes Auslassen von break Wird das break in den case-Abschnitten vergessen, so wird die darunterliegende Marke ebenfalls abgearbeitet. Dies passiert so lange, bis entweder das nächste break erreicht wird oder das gesamte switch-Statement beendet ist. Obwohl dieser Fall meist unerwünscht ist, lässt sich diese Funktionalität trotzdem nützlich einsetzen, um andere Pfade ebenfalls mit abzulaufen. 1 2 3 4 5 6 7 8 char eingabe ; cout << " Geben Sie X zum beenden ein .\ n " ; cin >> eingabe ; switch ( eingabe ) { case 'X ': ; // keine Funktion , nutzt naechste case - Marke case 'x ': cout << " Programm wird beendet " ; break ; } Das Beispiel zeigt, dass im Menü sowohl bei der Eingabe von X als auch bei x die gleiche Funktionalität aufgerufen wird, da das break nach Zeile 5 absichtlich weggelassen wurde und dadurch die Verarbeitung bei der nächsten case-Marke fortfährt. 30 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Überblick 1 Entscheidungen und Abfragen if-Abfragen Bedingungen definieren ``Wenn dann sonst''-Abfragen mit else Mehrere Bedingungen prüfen mit booleschen Funktionen 2 Fallunterscheidungen Das switch-Statement 3 Visualisierung des Programmablaufs 31 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Motivation Durch die Verzeigungsmöglichkeiten, die wir in diesem Abschnitt kennengelernt haben, ist der Programmfluss nicht mehr linear (zeilenweise). Aus diesem Grund macht es Sinn, für die weitere Programmierung den Programmfluss zu visualisieren. Gerade, wenn die Programm grösser und komplexer werden, sollten diese vorher skizziert werden, um z.B. zu gewährleisten, dass alle Pfade in if else auch mit Programmlogik versehen sind. Bevor wir also an das Erstellen von Programmtext in der IDE gehen, sollte der Programmfluss und Ablauf strukturiert sein. Ist dieser erstmal klar, ist die Übertragung in Programmcode nicht mehr allzu schwierig. Mitteln DIN-genormter Diagramme können wir für uns und andere Programmierer unsere Gedanken zum Programmablauf als Entwurfsmethode strukturiert darstellen. Eine solche Diagrammart sind sogenannte Struktogramme nach DIN 66261. 32 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Regeln für die Erstellung von Struktogrammen Die folgenden Regeln gelten für die Erstellung von Struktogrammen: Anweisungsexklusivität Jede Anweisung erhält einen eigenen Block, um die Übersichtlichkeit zu erhalten. Beispiel: Sprachunabhängig Es wird keine programmiersprachliche Syntax verwendet, da man sich zu diesem Zeitpunkt erst um den Algorithmus im Klaren sein sollte, als um die Frage, mit welcher Sprache dies geschehen soll. Die so dargestellte Logik sollte möglichst einfach zu verstehen sein, z.B. zaehler um eins erhöhen. Es handelt sich dabei also um Pseudocode. Deklarationslosigkeit In einfachen Struktogrammen werden keine Variablen- und Konstantendeklarationen als Anweisungen beschrieben. Es soll durch das Diagramm der Ablauf und die Struktur des Programms ersichtlich werden. 33 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Linearer Programmablauf als Struktogramm Jede Anweisung wird im Struktogramm als separates Kästchen gezeichnet. Lineare Programme werden wie folgt dargestellt: Der Programmablauf beginnt oben und wird nach unten hin durchlaufen. Ein leerer Strukturblock ist nur in Verzweigungen möglich. 34 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Einfache Verzweigungen mit Struktogrammen darstellen Eine einfache if-Abfrage kann mit einem Struktogramm folgendermassen dargestellt werden: Da es keinen else-Abschnitt gibt, wird die rechte Seite (Nein) leer bleiben. Beispiel 35 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Zweifache Verzweigungen mit Struktogrammen darstellen Eine if else-Abfrage wird mit gefülltem Nein-Abschnitt beschrieben: Beispiel 36 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Verschachtelte Abfragen mit Struktogrammen darstellen Verschachtelte if-else Abfragen lassen sich durch die konsequente Anwendung der bisherigen Regeln ebenfalls visualisieren. Beispiel Natürlich ist sowohl nur im Nein-Abschnitt als auch in beiden (Ja und Nein) eine Verschachtelung möglich. 37 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Fallunterscheidungen mit Struktogrammen beschreiben Das switch case-Statement lässt sich inklusive dem optionalen default-Abschnitt so darstellen: Beispiel Weitere Darstellungsmöglichkeiten werden wir im Laufe der Vorlesung noch kennenlernen. 38 / 39 Kontrollstrukturen -- Entscheidungen, Abfragen und Fallunterscheidungen Visualisierung des Programmablaufs Struktogrammeditoren Es existieren eine Reihe von Editoren zur Erstellung von Struktogrammen. Ein paar davon sind hier aufgeführt: http://www.learn2prog.de/ http://structorizer.fisch.lu/ http://www.whiledo.de/programm.php?p=struktogrammeditor 39 / 39