Informatik für Ingenieure (InfIng) C - Kontrollstrukturen Doz. Dipl.-Ing. H. Hiller WS 2012/13 Kontrollstrukturen Erinnern Sie sich ? Frühstücks-Ei kochen, 6 Minuten Was tun, wenn… … kein Topf vorhanden ist? … Herdplatte schon besetzt ist? … die Eier noch im Karton sind? Was tun, wenn's nicht geradeaus läuft? Start Öffne Schrank. Nimm Topf. Programme sind wie das Leben Nichts läuft einfach nur geradeaus! Vieles macht man doppelt! Manches macht man auch dreifach! Anderes macht man erst gar nicht! Schließe Schrank. : Stop FH D Fachhochschule Düsseldorf Seite 2 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Kontrollstrukturen Kontrollstrukturen erlauben es… …vom sequenziellen Ablauf eines Programms abzuweichen Start anweisung_1 Wiederhole anweisung_2 solange, bis ein bestimmter Wert in anweisung_2 erreicht wird. anweisung_2 anweisung_3 Führe anweisung_4 nur dann aus, wenn die vorhergehende anweisung_3 einen gültigen Wert geliefert hat. Überspringe alle Anweisungen, wenn nicht alle Eingangsbedingungen erfüllt sind. anweisung_4 Stop FH D Fachhochschule Düsseldorf Seite 3 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Bedingungen Bedingungen Verzweigungen und Schleifen basieren auf Bedingungen Bedingungen können wahr oder falsch sein Ausführung erfolgt nur, wenn Bedingung erfüllt ist (also wahr ist) Wahr und Falsch Viele Programmiersprachen kennen den Datentyp BOOLEAN BOOLEAN hat 2 Werte: Wahr und Falsch bzw. TRUE und FALSE C kennt diesen Datentyp nicht Wahrheitsprüfung in C liefert immer einen Integerwert Integerwert ist von Null verschieden, wenn der Vergleich wahr ist Integerwert ist gleich Null, wenn der Vergleich falsch ist Wahr: ungleich 0 FH D Fachhochschule Düsseldorf Falsch: gleich 0 Seite 4 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Themen dieser Vorlesung Wir wollen folgenden Fragen nachgehen: 1. "Wie kann man bedingt Anweisungen ausführen?" Verzweigungen 2. "Wie kann man Anweisungen wiederholen?" Schleifen 3. "Wie kann man Anweisungen ab- bzw. unterbrechen?" Sprünge FH D Fachhochschule Düsseldorf Seite 5 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Übersicht Verzweigungen Schleifen Sprunganweisungen FH D Fachhochschule Düsseldorf Seite 6 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Bedingte Verzweigung Wahrheitswert entscheidet über die Ausführung von Anweisungen Syntax der if-Anweisung if (ausdruck) anweisung_1; else anweisung_2; ausdruck falsch wahr anweisung_1 anweisung_2 ausdruck ist wahr: Ausführung von anweisung_1 ausdruck ist falsch: Ausführung von anweisung_2 Einfach Alternative else ist optional und kann weggelassen werden ausdruck if (ausdruck) anweisung; wahr ausdruck ist wahr: Ausführung von anweisung_1 ausdruck ist falsch: anweisung_1 wird übersprungen FH D Fachhochschule Düsseldorf falsch Seite 7 Informatik für Ingenieure WS 2012/13 anweisung_1 FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Einrückungen Ohne Bedeutung für den Compiler "Nur" ein Appell an die Lesbarkeit :-)) Runde Klammern Pflicht für das Argument der if-Anweisung Geschweifte Klammern if (ausdruck) { anweisung_1; anweisung_2; } else { anweisung_3; } Optional bei lediglich einer Anweisung Pflicht bei zwei oder mehr Anweisungen Klammern bestimmen den Programmablauf Gleiche if - Anweisung, verschiedene Klammerung Welche Anweisungen werden ausgeführt? – – #1: Keine Anweisung wird ausgeführt #2: Ausgeführt wird anweisung_2 Was liegt hier vor: Absicht oder Fehler? – Einrückung der anweisung_2 spricht für Fehler… FH D Fachhochschule Düsseldorf Seite 8 Informatik für Ingenieure WS 2012/13 if (1 > 3) { anweisung_1; anweisung_2; } if (1 > 3) anweisung_1; anweisung_2; #1 #2 FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Beispiel Programm soll prüfen, ob ein gegebenes Zeichen ein kleiner Buchstabe ist Ist das Zeichen ein Kleinbuchstabe, so ist der zugehörige ASCII-Wert auszugeben #include <stdio.h> #include <ctype.h> int main() { char c = 'm'; if ( (c >= 'a') && (c <= 'z') { printf ("Das Zeichen %c ist printf ("Der ASCII-Wert ist } else { printf ("Was weiss ich, was } return 0; ) ein kleiner Buchstabe.\n", c); %ddez.\n", c); das für ein Zeichen ist..."); } FH D Fachhochschule Düsseldorf Seite 9 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Schachtelung else gehört immer zum unmittelbar vorhergehenden if Fehler bei Klammer oder Semikolon verändern den Programmablauf Beispiel Verändern einer Klammer bei geschachtelter if-Anweisung if (x > if (y a = else a = 0) > 0) 1; 2; Ohne Klammern gehört das else zum zweiten if. FH D Fachhochschule Düsseldorf if (x > { if (y a = else a = } 0) > 0) 1; 2; Mit Klammern funktional kein Unterschied zu A, aber übersichtlicher. Seite 10 Informatik für Ingenieure WS 2012/13 if (x > { if (y a = } else a = 0) > 0) 1; 2; Mit zweiter Klammer etwas früher gesetzt, gehört das else zum ersten if FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Mehrfachverzweigung Verzweigung über mehrere Alternativen mittels else..if Syntax der Mehrfachverzweigung if (ausdruck_1) anweisung_1; else if (ausdruck_2) anweisung_2; else if (ausdruck_n) anweisung_n; else anweisung_m; ? ? a_1 ? a_2 a_n a_m Auswertung der Ausdrücke in vorgegebener Reihenfolge Ergibt eine der Auswertungen wahr, wird die zugehörige Anweisung ausgeführt Ist kein Ausdruck wahr, wird die Anweisung im (letzten) else-Zweig ausgeführt FH D Fachhochschule Düsseldorf Seite 11 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Bedingte Verzweigung (if..else) Bedingungsoperator (?:) Alternative zur Verwendung der Schlüsselwörter if und else Syntax ausdruck ? anweisung_1 : anweisung_2 Tenärer Operator ?: ist ein tenärer Operator (der einzige übrigens in ANSI C) if (a > b) { x = 0; } else { x = 1; } FH D Fachhochschule Düsseldorf ist äquivalent mit (a > b) ? (x = 0) : (x = 1); oder noch etwas raffinierter ausgedrückt x = (a > b) ? 0 : 1; Seite 12 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Fallunterscheidung (switch) Fallunterscheidung Berücksichtigung mehrerer Alternativen, nicht nur wahr oder falsch Prinzipiell auch mit if..else möglich (Nachteil: unübersichtlicher) Syntax der switch - Anweisung switch (ausdruck) { case const_1: case const_n: default: anweisung_1; break; anweisung_n; break; anweisung_x; } Auswertung des Ausdrucks liefert einen Wert vom Typ Integer Ergebnis wird verglichen mit den case - Lables (ganzzahlige Konstanten) Anschließend Sprung zu case - Lable, das mit Ergebnis übereinstimmt Fehlende Übereinstimmung führt zum (optionalen) default-Lable FH D Fachhochschule Düsseldorf Seite 13 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Fallunterscheidung (switch) Abschluss eines case-Blocks mittels break Anweisungen der nachfolgenden case - Lables werden nicht ausgeführt Programm wird nach der schließenden geschweiften Klammer fortgesetzt switch (ausdruck) { case const_1: anweisung_1; break; case const_2: anweisung_2a; anweisung_2b; Fallthrough case const_3: anweisung_3; break; Einsprung A Einsprung B default: anweisung_x; } Verzicht auf break am Ende eines case-Blocks Nachfolgendes case-Lable wird ebenfalls ausgeführt (ggf. auch weitere Lables) Prg.-Ausführung bis zum nächsten break bzw. Ende des switch (Fallthrough) FH D Fachhochschule Düsseldorf Seite 14 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Fallunterscheidung (switch) Beispiel Ausgabe der Anzahl Tage eines Monats #include <stdio.h> int main() { int monat = 2; switch (monat) { case 1: printf("31 Tage"); break; case 2: printf("28 Tage"); break; case 7: case 8: printf("31 Tage"); break; // Monat Januar hat 31 Tage // Sprung zum Ende von switch // weitere Lables für 3 bis 6 // Falltrough, da Juli und // August beide 31 Tage haben // weitere Lables für 9 bis 12 default: printf("Kein gueltiger Monat"); } return 0; } FH D Fachhochschule Düsseldorf Seite 15 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Übersicht Verzweigungen Schleifen Sprunganweisungen FH D Fachhochschule Düsseldorf Seite 16 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Schleifen Schleifen Wiederholung einer oder mehrerer Anweisungen Realisierung jeglicher Formen von "Zählen" Anzahl Schleifendurchläufe Vorgegeben oder im Programmverlauf ermittelt Abbruchbedingung … steuert die Schleifendurchläufe … ist ein logischer Ausdruck (liefert wahr oder falsch) … wird vor oder nach jedem Durchlauf überprüft 3 Arten von Schleifen while - Schleife do..while - Schleife for - Schleife © Jochen Seelhammer - Fotolia.com FH D Fachhochschule Düsseldorf Seite 17 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien while - Schleife while - Schleife Vorprüfende bzw. abweisende Schleife Syntax der while - Schleife falsch ausdruck wahr while (ausdruck) anweisung; anweisung Schleifendurchläufe Abbruchbedingung wird vor Eintritt geprüft Kein Schleifendurchlauf wenn ausdruck falsch Anzahl der Schleifendurchläufe 0..n while (a < b) { // Anweisung x a = a + 1; } printf("a=%d",a); FH D Fachhochschule Düsseldorf Seite 18 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien while - Schleife Beispiel Auszugeben sind alle Integer-Zahlen von 0 bis 4 #include <stdio.h> int main() { int i = 0; while (i <= 4) { printf ("i = %d\n", i); i = i + 1; }; return 0; } Was geschieht, wenn i zu Programmbeginn auf 5 gesetzt wird? FH D Fachhochschule Düsseldorf Seite 19 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien do..while - Schleife do..while - Schleife Nachprüfende bzw. nicht-abweisende Schleife Syntax der do..while - Schleife anweisung do anweisung; while (ausdruck); wahr ausdruck falsch Anzahl Schleifendurchläufe Abbruchbedingung wird nach Durchlauf geprüft Schleife wird mindestens einmal durchlaufen Anzahl der Schleifendurchläufe 1..n do { // Anweisung x a = a + 1; } while (a > b); printf("a=%d",a); FH D Fachhochschule Düsseldorf Seite 20 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien do..while - Schleife Beispiel Auszugeben sind alle Integer-Zahlen von 0 bis 4 #include <stdio.h> int main() { int i = 0; do { printf ("i = %d\n", i); i = i + 1; } while (i <= 4); return 0; } Was geschieht, wenn i zu Programmbeginn auf 5 gesetzt wird? FH D Fachhochschule Düsseldorf Seite 21 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien for - Schleife for - Schleife Vorprüfende bzw. abweisende (Zähl-) Schleife Syntax falsch ausdruck for (ausdruck_1; ausdruck_2; ausdruck_3) anweisung; ausdruck_1: ausdruck_2: ausdruck_2: wahr anweisung Laufindex, Initialisierung Abbruchkriterium Laufindex, Inkrementierung / Dekrementierung Funktion Init des Laufindexes bei Schleifeneintritt (ausdruck_1) Auswertung der Abbruchbedingung (ausdruck_2) Wenn ausdruck_2 wahr ist, dann … – – … durchlaufe die Schleife und … schalte dem Laufindex weiter (ausdruck_3) Laufindex – for (i=0;i<n;i++) { // Anweisung x a = a + i; }; printf("a=%d",a); Inkrementierung (z.B. i++) oder Dekrementierung (z.B. i--) FH D Fachhochschule Düsseldorf Seite 22 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien for - Schleife Beispiel Auszugeben sind alle Integer-Zahlen von 0 bis 4 #include <stdio.h> int main() { int i; for (i=0; i<=4; i++) { printf ("i = %d\n", i); } return 0; } Keine separate Anweisung für die Laufvariable i (i = i+1 bzw. i++) FH D Fachhochschule Düsseldorf Seite 23 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Hörsaalübung Übung 1 Ausgabe aller Großbuchstaben (A .. Z) #include <stdio.h> #include <stdio.h> int main() { int i; for (i='A'; i<='Z'; i++) { printf ("%c ", i); } return 0; } int main() { int i = 'A'; do { printf ("%c ", i++); } while (i<= 'Z'); return 0; } Beide Schleifen sind gleichwertig für die Lösung dieser Aufgabe. Präferenz hat die for – Schleife, da übersichtlicher. FH D Fachhochschule Düsseldorf Seite 24 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Hörsaalübung Übung 2 Gegeben sei eine Variable name als ein Array mit 21 Feldern Es ist die Länge eines in name gespeicherten Vornamens zu ermitteln #include <stdio.h> int main() { char name[21] = "Snoopy"; int i = 0; while (name[i] != '\0') { printf ("name[%i] = %c\n", i, name[i]); i = i + 1; } printf ("%s hat %d Buchstaben", name, i); return 0; // Pruefung auf NUL-Byte // Laufindex erhoehen } FH D Fachhochschule Düsseldorf Seite 25 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Hörsaalübung Übung 3 Aufforderung zur Eingabe eines kleinen Buchstabens Eingabeaufforderung ist bei Falscheingabe (z.B. einer Zahl) zu wiederholen #include <stdio.h> int main() { char eingabe; do { printf ("Eingabe Kleinbuchstabe: "); // Eingabeaufforderung eingabe = getchar(); // Einlesen von der Tastatur fflush(stdin); // Tastaturbuffer loeschen } while ( (eingabe < 'a') || (eingabe > 'z') ); printf ("\nEs wurde der Buchstabe %c eingegeben", eingabe); return 0; } FH D Fachhochschule Düsseldorf Seite 26 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Verschachtelte Schleifen Verschachtelte Schleifen Keine Einschränkungen für Anweisungen im Schleifenkörper Somit können auch Schleifen in einer Schleife vorkommen Schleifen werden durch übergeordnete Schleifen kontrolliert for (...) for (...) for (...) Verschachtelungstiefe Ausgedrückt durch die Anzahl an Ebenen abhängiger Schleifen Prinzipiell keine Begrenzung Mehr als drei Ebenen führen zu schwer verständlichem Code Uhrenvergleich ;-) Äußere Schleife entspricht dem Stundenzeiger Innere Schleife entspricht dem Minutenzeiger Während der Stundenzeiger um eine Einheit vorrückt, absolviert der Minutenzeiger einen kompletten Umlauf. © Heino Pattschull - Fotolia.com FH D Fachhochschule Düsseldorf Seite 27 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Verschachtelte Schleifen Beispiel Ausgabe der Ziffern 0 bis 49 in 5 Zeilen #include <stdio.h> int main() { int i, j; // Laufindizes der beiden Schleifen for (i=0; i <5; i++) { for (j=0; j< 10; j++) { printf("%d%d ", i, j); } printf ("\n"); } return 0; // aeussere Schleife, vgl. std-Zeiger // innere Schleife, vgl. min-Zeiger } FH D Fachhochschule Düsseldorf Seite 28 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Endlosschleife Endlosschleife Ausführung einer Schleife ohne Unterbrechung anweisungen Beabsichtigte Endlosschleifen Steuerungs-Algorithmen (z.B. Maus, Multitaskingsysteme) Applets (z.B. animierte Applets auf Webseiten) schleife Unbeabsichtigte Endlosschleifen Mögliche Programmierfehler – – Schleife ohne Abbruchbedingung Schleife mit Abbruchbedingung, aber unerfüllbar anweisungen Mögliche Auswirkungen – – Inaktivität des Programms dem Benutzer gegenüber ("Einfrieren") Absturz des Rechners durch hohe Ressourcenauslastung Endlosschleifen im täglichen Leben Akustischer Kurzschluss, Bild im Bild Wiederholte Ausgabe/Aufnahme eines Schallmusters/Bildes © WoGi - Fotolia.com FH D Fachhochschule Düsseldorf Seite 29 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Endlosschleife Beispiele 3 Endlosschleifen – 1 beabsichtigt, 2 unbeabsichtigt (Fehler) Endlosschleife #1 Endlosschleife #2 Endlosschleife #3 #include <stdio.h> #include <stdio.h> #include <stdio.h> int main() { while (1) { printf("Endlos"); } return 0; } int main() { int i=0; while (i < 10) { printf("i=%d",i); } return 0; } int main() { int i=0; while (i < 10); { printf("i=%d",i); } return 0; } Finden Sie die Fehler bei Endlosschleife #2 und #3 FH D Fachhochschule Düsseldorf Seite 30 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Übersicht Verzweigungen Schleifen Sprunganweisungen FH D Fachhochschule Düsseldorf Seite 31 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien continue Sprung aus einer Schleife Abbruch eines Schleifendurchlaufs Restlicher Code im Schleifenblock wird übersprungen Schleife wird mit nächster Iteration fortgeführt while (ausdruck) { ... continue; ... } Syntax continue; Beispiel Summenbildung über gerade ganzzahlige Zahlen von i bis 10 while (i < 11) { i = i + 1; if (i % 2) continue; s = s + i; printf("i = %d } FH D Fachhochschule Düsseldorf // Module-Operation // Abbruch der Iteration bei ungeraden Zahlen s = %d\n", i, s); Seite 32 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien break Sprung aus switch - Anweisung oder Schleife switch: Verlassen der switch - Anweisung Schleife: Verlassen der Schleife, keine weitere Iteration Programm wird mit nächster Anweisung fortgeführt Syntax while (ausdruck) { ... break; ... } ... break; Beispiel Summenbildung über ganzzahlige Zahlen while (i < 11) { i = i + 1; s = s + i; if (s > 10) break; } printf("i = %d FH D Fachhochschule Düsseldorf s = %d\n", i, s); Seite 33 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien return Rücksprung aus einer Funktion Rücksprung in die aufrufende Funktion, bzw. an die aufrufende Stelle Optional: Übergabe eines (Rückgabe-) Wertes an die aufrufende Funktion Rücksprung an jeder Stelle möglich, vorzugsweise am Ende einer Funktion Syntax return ausdruck; ausdruck: Datentyp ist festgelegt in Funktionsdefinition Beispiel Rücksprung an die aufrufende Stelle, bzw. Funktion in main() { // Anweisungen funktion_A; } FH D Fachhochschule Düsseldorf int funktion_A { ergebnis = summe(1,3); return; } Seite 34 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien goto Sprung innerhalb einer Funktion Sprungziel muss durch eine Marke gekennzeichnet sein Programm wird nach der Sprungmarke fortgesetzt anweisung_1 Syntax goto goto sprungmarke; : sprungmarke: anweisung; anweisung_2 sprungmarke sprungmarke: Sprungadresse innerhalb einer Funktion anweisung_3 Verwendung von goto Unüberlegter Einsatz von goto führt leicht zu unübersichtlichen Programmen Einziger sinnvolle Einsatz: Abbruch einer mehrfach geschachtelten Schleife Formal ist goto niemals notwendig Einsatz von Schleifen anstelle von goto Sprunganweisungen mit goto widersprechen den Prinzipien der strukturierten Programmierung. FH D Fachhochschule Düsseldorf Seite 35 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien goto Beispiel Auszugeben sind alle Zahlen von 0 bis 4 #include <stdio.h> #include <stdio.h> int main() { int i = 0; int main() { int i = 0; anfang: printf("i = %i\n", i++); if (i <= 4) goto anfang; return 0; } ohne goto while (i <= 4) { printf("i = %i\n", i++); } return 0; } Formal ist goto niemals notwendig. Jeder Algorithmus lässt sich durch Verzweigungen und Schleifen realisieren! FH D Fachhochschule Düsseldorf Seite 36 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien Kreisverkehr ? Endlosschleife ! © Klaus Eppele - Fotolia.com FH D Fachhochschule Düsseldorf Seite 37 Informatik für Ingenieure WS 2012/13 FB 5 Fachbereich Medien