Algorithmen & Programmierung Steuerstrukturen im Detail Selektion und Iteration
Selektion
Selektion Vollständige einfache Selektion Wir kennen schon eine Möglichkeit, Selektionen in C zu formulieren: if ( Ausdruck ) Anweisung1 else Anweisung2 Allerdings ist diese Variante nur ein Spezialfall des allgemeineren Konzepts Selektion, denn es wird in Abhängigkeit des Ergebnisses der Auswertung von Ausdruck aus genau zwei Varianten selektiert: Anweisung1 (bei true) oder Anweisung2 (bei false) Kennzeichen der Selektion Anzahl zu selektierender Varianten Relation zu selektierenden Varianten Selektionskriterien 319
Selektion Bedingte Anweisung Die einfachste Form einer Selektion wird auch als unvollständige Selektion bezeichnet: if ( Ausdruck ) Anweisung Besonderes Merkmal Die bedingte Anweisung besitzt keinen else-zweig. Ablauf Anweisung wird nur ausgeführt, wenn Ausdruck nach true ausgewertet werden kann. Wenn Ausdruck nach false ausgewertet wird, spielt das für die weitere Abarbeitung keine Rolle. 320
Unvollständige Selektion Beispiel Webshop Sie möchten ein Buch kaufen und können sich nach der Wahl des Buches für den kostenlosen Standardversand oder den schnellen, aber 5 teuren Expressversand entscheiden. int Betrag() { int summe; bool zuschlag; summe = 59; zuschlag = true; if (!zuschlag) return summe; else summe += 5; return summe; } Dr. Frank Seifert Anzahl Artikel 1 Preis 59 Expresszuschlag 5 Summe 64 Vorlesung Algorithmen & Programmierung WS 2015/2016 int Betrag() { int summe; bool zuschlag; summe = 59; zuschlag = true; if (zuschlag) summe += 5; return summe; } 321
Geschachtelte Selektionen Selektionen können geschachtelt werden. Dabei wird statt der auszuführenden Anweisung wieder eine Selektion eingesetzt. Dieser Vorgang kann beliebig oft wiederholt werden: Beispiel für geschachtelte vollständige Selektionen if ( Ausdruck1 ) if ( Ausdruck2 ) Anweisung1 else Anweisung2 else if ( Ausdruck3 ) Anweisung3 else Anweisung4 Wenn der Wert von Ausdruck1 zu true korrespondiert, dann wird in Abhängigkeit der Auswertung von Ausdruck2 entweder Anweisung1 oder Anweisung2 ausgeführt. sonst (Wenn der Wert von Ausdruck1 zu false korrespondiert) wird in Abhängigkeit der Auswertung von Ausdruck3 entweder Anweisung3 oder Anweisung4 ausgeführt. 322
Geschachtelte Selektionen Problem Da statt vollständiger Selektionen auch unvollständige Selektionen geschachtelt werden können, taucht die Frage auf, wie bei gemischten vollständigen und unvollständigen Selektionen die Zuordnung durchgeführt wird. Regel Ein else-zweig gehört immer zum letzten if-statement. Achtung Der Compiler ordnet einen else-zweig immer nach obiger Regel zu. Wenn andere Zuordnungen gewünscht sind, muss dies durch Blockbildung erzwungen werden. Dies ist eine häufige Fehlerquelle, die oft (z.b. aufgrund manuell vorgenommener falscher Einrückungen) schwer zu entdecken ist. Abhilfe Anweisungen geschachtelter Selektionen sollten besser immer in Blöcken eingebettet werden. 323
Mehrfachselektion Spezialfall geschachtelter Selektionen Werden Selektionen nur im else-zweig geschachtelt, spricht man von Mehrfachselektionen. Anwendung Mehrfachselektionen dienen zur Modellierung von mehr als zwei Zuständen. Ablauf Ist Ausdruck1 erfüllt wird Anweisung1 ausgeführt, sonst wird Ausdruck2 getestet und gegebenenfalls Anweisung2 ausgeführt usw., d.h. nur wenn ein Ausdruck false ergibt, wird die Mehrfachselektion weiter abgearbeitet. Falls keine Bedingung in der Mehrfachselektion gültig ist, wird die optionale Anweisungn+1 ausgeführt. if (Ausdruck1) Anweisung1 else if (Ausdruck2) Anweisung2 else if (Ausdruck3) Anweisung3 else if (Ausdruckn) else Anweisungn Anweisungn+1 324
Mehrfachselektion - Schreibweise Statt der links dargestellten unübersichtlichen Form verwendet man meist die rechts gezeigte Variante: if (Ausdruck1) Anweisung1 else if (Ausdruck2) Anweisung2 else if (Ausdruck3) Anweisung3 else if (Ausdruckn) else Anweisungn Anweisungn+1 if (Ausdruck1) Anweisung1 else if (Ausdruck2) Anweisung2 else if (Ausdruck3) Anweisung3 else if (Ausdruckn) Anweisungn else Anweisungn+1 325
Mehrfachselektion - Spezialfall Häufige Situation Die Mehrfachselektion basiert nur auf verschiedenen Werten derselben Variable oder desselben Ausdrucks. Alternative Verwendung des nebenstehend dargestellten switch-statements anstelle der Mehrfachselektion. Voraussetzung Die Werte des Ausdrucks oder der Variable müssen sich ganzzahlig beschreiben lassen. switch ( Ausdruck ) { } case Literal1 : Anweisung1 [ break; ] case Literal2 : Anweisung2 [ break; ] case Literaln : Anweisungn [ break; ] [ default: Anweisung ] 326
Mehrfachselektion - switch switch ( Ausdruck ) { } case Literal1 : Anweisung1 [ break; ] case Literal2 : Anweisung2 [ break; ] case Literaln : Anweisungn [ break; ] [ default: Anweisung ] Ablauf Besitzt Ausdruck einen Wert, der einem der Literale Literal1 bis Literaln entspricht, wird das Programm mit der Anweisung hinter der entsprechenden case-marke fortgeführt. Stimmt der Wert von Ausdruck mit keinem der Literale Literal1 bis Literaln überein, wird das Programm mit der Anweisung hinter der default-marke fortgeführt. Da die default-marke optional ist, wird bei Nichtvorhandensein mit der Anweisung nach dem switch-statement fortgefahren. Anmerkung Die Reihenfolge der case-marken ist beliebig. Es empfiehlt sich allerdings eine sinnvolle Sortierung. 327
Mehrfachselektion - switch switch ( Ausdruck ) { } case Literal1 : Anweisung1 [ break; ] case Literal2 : Anweisung2 [ break; ] case Literaln : Anweisungn [ break; ] [ default: Anweisung ] Achtung Es werden alle Anweisungen nach einer case-marke abgearbeitet, auch die Anweisungen anderer case-marken. Die Abarbeitung wird erst durch eine break-anweisung unterbrochen (oder durch Erreichen des Endes des switch-statements). Diese auf den ersten Blick etwas unlogisch erscheinende Eigenschaft ermöglicht eine flexible gemeinsame Verarbeitung von Wertekombinationen. Anmerkung Aufgrund des expliziten Abbruchs der Verarbeitung durch break ist eine Blockbildung hinter einer case-marke nicht nötig. 328
switch versus else-if Vorteile von switch Vorteile von else-if übersichtlicher besser erweiterbar meist effizienter, da sich wegen der konstanten case-marken schon während der Übersetzung Optimierungsmöglichkeiten für den Compiler bieten, während bei elseif die Auswertung in der Regel erst zur Laufzeit erfolgen kann switch prüft nur auf Werte- Gleichheit, else-if kann auch komplexere Bedingungen testen switch verarbeitet nur ganzzahlige Werte, else-if kann beliebige Werte verarbeiten 329
Iteration
Abweisende Schleife Wir kennen schon eine Möglichkeit, Iterationen in C zu formulieren - die Steuerstruktur while: Ablauf while ( Ausdruck ) Anweisung Wenn Ausdruck nach true evaluiert werden kann, wird Anweisung ausgeführt. Danach wird Ausdruck erneut getestet und gegebenenfalls Anweisung erneut ausgeführt usw. Abweisende Schleife Diese Form der Realisierung einer Iteration wird auch als abweisende Schleife bezeichnet, denn die Anweisung wird nur ausgeführt, wenn der Ausdruck im Vorhinein erfüllt ist. Achtung Damit keine Endlosschleife auftritt, muss durch die Anweisung ein Lvalue-Bestandteil von Ausdruck verändert werden. 331
Annehmende Schleife Definition Manchmal ist es notwendig, dass eine Aktion mindestens einmal durchgeführt wird, bevor entschieden werden kann, ob sie wiederholt wird. do Anweisung while ( Ausdruck ) ; Ablauf Die Anweisung wird definitiv einmal abgearbeitet. Kann anschließend der Ausdruck nach true evaluiert werden, dann wird die Anweisung erneut ausgeführt usw. Achtung Bei der do-while-schleife wird (im Gegensatz zur abweisenden Schleife) nach der Schleifenbedingung zwingend ein Semikolon verlangt, da das Ende der Anweisung erreicht ist. 332
do-while while Transformation einer annehmenden in eine abweisende Schleife Die Anweisung muss vor Beginn der abweisenden Schleife genau einmal ausgeführt werden und wird deshalb vor den abweisenden Schleifenrumpf kopiert. Ausdruck und Anweisung werden aus der annehmenden in die abweisende Schleifenvariante unverändert übernommen. do Anweisung Anweisung while ( Ausdruck ) ; while ( Ausdruck ) Anweisung 333
while do-while Transformation einer abweisenden in eine annehmende Schleife Der Ausdruck muss zusätzlich vor Beginn der annehmenden Schleife geprüft werden. Deshalb wird der annehmende Schleifenrumpf in eine unvollständige Selektion eingebettet. Ausdruck und Anweisung werden aus der abweisenden in die annehmende Schleifenvariante unverändert übernommen. if ( Ausdruck ) { while ( Ausdruck ) Anweisung do Anweisung while ( Ausdruck ) ; } 334
Typische Iteration Typischer Ablauf einer Iteration 1. Definition einer Zählvariablen z 2. Initialisierung von z 3. Wenn z einer bestimmten Bedingung genügt, dann 3.1. führe eine oder mehrere Anweisungen aus 3.2. verändere z auf die gleiche Weise 3.3. gehe zu 3. Kompaktere Darstellung Aufgrund des häufigen Vorkommens dieses Ablaufs gibt es in C eine Möglichkeit, die Schritte 2, 3, 3.2 und manchmal sogar Schritt 1 in einer speziellen Steuerstruktur zusammenzufassen. 335
Die for-schleife Variante mit while-schleife: Formulierung der for-schleife (bzgl. Situation der Vorfolie) Definition einer Zählvariablen z ; for ( Initialisierung von z ; Bedingung mit z ; Änderung von z ) Anweisung Definition einer Zählvariablen z ; Initialisierung von z ; while ( Bedingung mit z ) { Anweisung ; Änderung von z ; } oder alternativ noch kompakter for ( Definition und Initialisierung einer Zählvariablen z ; Bedingung mit z ; Änderung von z ) Anweisung 336
Die for-schleife Abweisende Schleife Die for-schleife ist semantisch nur eine kompaktere Darstellung einer while-schleife und demzufolge auch eine abweisende Schleife. Allgemeine Formulierung for ( Anweisung1 ; Ausdruck ; Anweisung3 ) Ablauf Anweisung2 Vor Beginn der Iteration wird eine beliebige Anweisung1 ausgeführt, die jedoch keine Blockanweisung sein darf und i.d.r. nur zur Initialisierung von Iterationsvariablen dient. Solange Ausdruck nach true evaluiert werden kann, wird Anweisung2 gefolgt von Anweisung3 ausgeführt, dabei dient Anweisung3 i.d.r. zur Veränderung einer Komponente von Ausdruck, damit irgendwann ein Abbruch der Iteration erreicht werden kann. 337
Ende der Vorlesung