Programmierkurs Birgit Engels, Anna Schulze ZAIK Universität zu Köln WS 07/08 Kapitel 5 Wiederholung Kapitel 5 Kontrollstrukturen Bis jetzt wurden in jedem Programm alle Befehle nacheinander einmal ausgeführt: Das Programm machte (bis auf unterschiedliche Eingabewerte) immer das gleiche. Sogenannte “Kontrollstrukturen” sind besondere Anweisungen, die es einem Programm ermöglichen, sich unterschiedlich zu verhalten oder Befehlsabfolgen mehrfach auszuführen. Arten von Kontrollstrukturen Bedingte Ausführung ◮ ◮ if/if ... else-Anweisung switch-Anweisung (Bedingte) Mehrfachausführung ◮ ◮ ◮ for-Schleife while-Schleife do ... while-Schleife 5.0 Die if-Anweisung if ( < Bedingung > ) < Anweisung > oder if ( < Bedingung > ) < Anweisung 1 > else < Anweisung 2 > < Bedingung > ist ein Wert ∈ {true, false}, eine Variable vom Typ boolean oder ein boolscher Ausdruck, der zu einem solchen Wert ausgewertet wird. Anweisung ist eine einzelne Anweisung oder ein Block von Anweisungen. Im ersten Fall wird die Anweisung nur ausgeführt, wenn die Bedingung den Wert true hat. Im zweiten Fall wird die Anweisung1 ausgeführt, wenn die Bedingung den Wert true hat. Andernfalls wird Anweisung2 ausgeführt. Fallunterscheidungen mit else if char c=’x’; int ascii; if (c==’a’) ascii=97; else if (c==’b’) ascii=98; ... else if (c==’z’) ascii=122; else ascii=0; Fallunterscheidungen mit else if sind bei vielen Fällen unkomfortabel und enthalten den Overhead der Vergleichsbedingung. Für solche Anwendungen verwendet man daher die switch- Anweisung. 5.0 Die switch-Anweisung switch (< Ausdruck >) { case < Wert1 > : < Anweisung >; break; case < Wert2 > : < Anweisung >; break; ... default : < Anweisung >; break; } < Ausdruck >: arithmetischer Ausdruck oder einzelne Variable. < Wert >: Wert, den < Ausdruck > annehmen kann. < Anweisung >: einzelne Anweisungen Block von Anweisungen. Die Anweisungen hinter default werden ausgeführt, falls < Ausdruck > keinen der < Wert >e annimt. switch vs. else if Die Zeile case < Wert > : < Anweisung >; break; einer switch-Anweisung entspricht in etwa der Zeile: (else) if (< Ausdruck >==< Wert >) < Anweisung >; einer else if-Anweisung. Die Zeile default : < Anweisung >; break; einer switch-Anweisung entspricht der letzten Zeile: else < Anweisung >; // einer else if-Anweisung. Nur im default-Fall darf break; weggelassen werden. Bemerkung zu break Es kann natürlich auch sinnvoll sein, einen Fall einer switch-Anweisung nicht mit break; abzuschliessen. Z.B.: Wenn in 2 Fällen die gleiche Anweisung folgen soll oder im ersten Fall nur zusätzliche Anweisungen zuvor auszuführen sind. Da ein weggelassenes break nur der Bequemlichkeit dient, ein vergessenes aber zu Fehlern führt, sollte generell jedes case mit einem break; abgeschlossen werden. 5.0 Die for-Schleife for (< Initialbefehl >; < Schleifenbedingung >; < Iteration > ) < Schleifenanweisung >; < Initialbefehl >: Einmalig durchgeführte Anweisung. Meist Deklaration+Initialisierung der Iterationsvariablen (Schleifenindex). < Schleifenbedingung >: Bedingung, die für die nächste Ausführung der < Schleifenanweisung > erfüllt sein muss. < Iteration >: Hochzählen des Schleifenindex. < Schleifenanweisung >: Einzelne Anweisung oder Block von Anweisungen. Verwendung der for-Schleife Die for-Schleife wird meist verwendet, um eine Folge von Anweisungen (Block) mehrfach auszuführen. Die Zahl der Ausführungen ist dabei oft vorher klar (feste Zahl oder begrenzt durch Wert einer Variablen). Daher werden for-Schleifen auch Zählschleifen genannt. Dabei werden immer folgende Schritte ausgeführt: 1. Initiatbefehl wird einmal ausgeführt. 2. Bedingung wird geprüft: ◮ ◮ Falls true: Anweisungen werden ausgeführt. Falls false: Schleife wird beendet. 3. Iteration wird ausgeführt. 4. Weiter bei 2. Häufigste Art der Verwendung: for( int i=0; i<xyz; i++) {tuwas;} Unbestimmte Schleifen Einzelne Elemente der for-Klammer können leer bleiben. Es funktioniert auch: for( ; ; ) {tuwas;} Dabei ist eine leere Bedingung immer wahr, d.h. hier wird tuwas; unendlich oft ausgeführt. Trotz leerer Bedingung können die Schleifendurchläufe gezählt werden: for(int i=1; ; i++ ) {tuwas;} Verlassen unbestimmter Schleifen Unbestimmte Schleifen können auf 2 Arten verlassen werden: 1. Es tritt eine “Ausnahme” (Exception) auf (später). 2. Die Schleife wird abhängig von einer Bedingung mit break verlassen: for(int i=1; ; i++ ) { if (i>10) break; } Beide Arten eine unbestimmte Schleife zu verlassen sind sehr unschön, da sie zu unübersichtlichen, schwer zu verifizierenden Programmen führen. Daher sollten unbestimmte Schleifen immer vermieden werden. Dies ist (manchmal aufwendiger, aber) immer möglich! Eine Programmiersprache ist mit break nicht mächtiger als ohne! break und continue Mit break wird eine Schleife komplett abgebrochen, falls die vorhergehende Bedingung erfüllt ist. Eventuell soll nur ein bestimmter Fall übersprungen werden, für den die Schleife nicht durchgeführt werden soll. Einmaliges überspringen des restlichen Schleifenkörpers gelingt mit: if (i==10) continue; Ist die Bedingung erfüllt springt das Programm direkt zum Ende des Durchlaufs und startet die Schleife mit dem nächsten Durchlauf. 5.0 Die while-Schleife while (< Schleifenbedingung >) < Schleifenanweisung >; < Schleifenbedingung >: Bedingung, die für die nächste Ausführung der < Schleifenanweisung > erfüllt sein muss. < Schleifenanweisung >: Einzelne Anweisung oder Block von Anweisungen, die ausgeführt werden, falls < Schleifenbedingung > true liefert. Verwendung der while-Schleife Im Gegesatz zur for-Schleife steht bei der while-Schleife die Schleifenbedingung, nicht die Anzahl der Schleifendurchläufe eher im Vordergrund. Um die Anzahl zu ermitteln, muss man selbst einen Zählindex verwalten. Die Schleifenbedingung ist ein eher komplexerer boolescher Ausdruck. Es werden immer folgende Schritte ausgeführt: 1. Bedingung wird geprüft: ◮ ◮ Falls true: Anweisungen werden ausgeführt. Falls false: Schleife wird beendet. 2. Weiter bei 1. Sonderfälle Eine leere Bedingung, ist bei while-Schleifen anders als bei for-Schleifen standardmässig nicht vorgesehen (erzeugt Kompilierfehler). Eine Endlosschleife mittels while wird mit true als Bedingung erreicht: while (true) < Schleifenanweisung >; Es gelten die gleichen Möglichkeiten zum verlassen einer solchen Endlosschleife mit while wie mit for: ◮ ◮ Exceptions break; Auch hier kann continue; zum Überspringen einer Ausführung verwendet werden. while-Schleifen können verschachelt werden (Blöcke bilden!). for vs. while Die while-Schleife und for-Schleife sind äquivalent, es gilt: for(Start; Bedingung; Änderung) Anweisung; entspricht: Start; while (Bedingung) { Anweisung; Änderung; } 5.0 Die do-Schleife do < Schleifenanweisung > while (< Schleifenbedingung >); < Schleifenanweisung >: Einzelne Anweisung oder Block von Anweisungen, die ausgeführt werden. < Schleifenbedingung >: Bedingung, die für die nächste Ausführung der < Schleifenanweisung > erfüllt sein muss. In do-Schleife entspricht der while-Schleife die allen Eigenschaften ausser dem Zeitpunkt der Bedingungsüberprüfung.