S. d. I.: Programieren in C Folie 4 - 1 4 Anweisungen 4.1 • if-Anweisung Syntax: 1) if (Ausdruck) { Anweisungsblock; }; 2) if (Ausdruck) { Anweisungsblock; } else { Anweisungsblock; }; • • im Gegensatz zu Pascal gibt es in C kein Schlüsselwort "then" es wird nur der numerische Wert des Ausdrucks geprüft, d.h. die Abfrage "if (x != 0)" entspricht der Kurzform "if (x)" (Die Kurzform sollte nur dann verwendet werden, wenn die Variable als boole'scher Wert verwendet wird und es keine Mißverständnisse geben kann) • die geschweiften Klammern sind nicht erforderlich, wenn der Anweisungsblock aus einer einzelnen Anweisung besteht ⇒ bei geschachtelten if-Anweisungen könnte es in diesem Fall zu ⇒ Fehlinterpretationen kommen, falls ein optionaler else-Teil folgt ⇒ dies wird dadurch vermieden, daß ein else immer dem nächsten ⇒ if ohne else-Teil zugeordnet wird Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C Folie 4 - 2 Beispiel: 1) if (x > if (a y = else y = 0) < b) a; b; 2) if (n > 0) for (i = 0; i < n; ++i) if (s[i] > 0) printf (...); else printf ("Fehler: n ist kleiner gleich 0.\n"); • im zweiten Beispiel erzeugt der Compiler ein falsches Programm, da er den else-Teil dem inneren if zuordnet und nicht dem äußeren if, wie es der Programmierer wünscht ⇒ solche Fehler werden vermieden, wenn auch einzelne Anweisun⇒ gen in geschweifte Klammern eingeschlossen werden ⇒ laut Programmierrichtlinien korrigiertes Programm: ⇒ if (n > 0) { for (i = 0; i < n; ++i) { if (s[i] > 0) { printf (...); }; }; } else { printf ("Fehler: n ist kleiner gleich 0.\n"); }; Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C • Folie 4 - 3 die Anweisung if (x < y) { z = x; } else { z = y; }; kann in Kurzform folgendermaßen geschrieben werden (ternärer Operator): z = x < y ? x : y; 4.2 • switch-Anweisung Syntax: switch (Ausdruck) { case konstanter Ausdruck: Anweisungsblock; ... case konstanter Ausdruck: Anweisungsblock; default: Anweisungsblock; }; • der Ausdruck muß eine ganze Zahl liefern (char, short, ...) • jede Alternative wird durch eine Konstante oder einen konstanten Ausdruck eingeleitet (nur ganze Zahlen sind erlaubt) Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C Folie 4 - 4 • vor einem Anweisungsblock dürfen mehrere Marken stehen • alle Marken müssen verschiedene Namen haben • • falls der Ausdruck mit keinem Markennamen übereinstimmt, wird der default-Teil verwendet, falls er vorhanden ist der default-Teil kann an jeder beliebigen Stelle stehen, an der eine Marke erlaubt ist (Vereinbarung: Er steht immer am Ende der switch-Anweisung) • sobald eine Alternative ausgewählt worden ist, werden alle Anweisungen bis zur nächsten break-, goto- oder return-Anweisung bzw. bis zum Ende der switch-Anweisung ausgeführt • die break-Anweisung bewirkt, daß die switch-Anweisung verlassen wird und als nächstes die Anweisung nach der switch-Anweisung ausgeführt wird • Beispiel: 1) switch (c) { case 'n': ...; break; case h: ...; break; default: ...; }; /* Optionen auswerten */ /* Zeilennummer drucken */ /* Hilfe ausgeben Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß */ S. d. I.: Programieren in C 2) int is_octal (char c) { switch (c) { case '0': case '1': case '4': case '5': return 1; default: return 0; }; }; 4.3 • Folie 4 - 5 case '2': case '6': case '3': case '7': while-Anweisung Syntax: while (Ausdruck) { Anweisungsblock; }; • solange der Ausdruck einen von Null verschiedenen Wert liefert, wird der Anweisungsblock ausgeführt • die geschweiften Klammern sind nicht erforderlich (aber in den Programmierrichtlinien gefordert), wenn der Anweisungsblock aus einer einzelnen Anweisung besteht • Beispiel: c = getchar (); while ((c == ' ') || (c == '\t') || (c == '\n')) { c = getchar (); }; Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C 4.4 • Folie 4 - 6 for-Anweisung Syntax: for (Ausdruck_1; Ausdruck_2; Ausdruck_3) { Anweisungsblock; }; • zuerst wird Ausdruck_1 ausgewertet. I.a. werden hier die Schleifenvariablen initialisiert. • dann wird Ausdruck_2 ausgewertet, der darüber entscheidet, ob der Anweisungsblock der Schleife ausgeführt wird oder nicht • falls Ausdruck_2 den Wert Null hat, wird anstelle des Anweisungsblocks der Schleife die nächste Anweisung nach der for-Anweisung ausgeführt • nachdem der Anweisungsblock der Schleife ausgeführt worden ist, wird Ausdruck_3 ausgewertet, der i.a. die Schleifenvariablen weiterschaltet • Ausdruck_1 wird nur einmal ausgewertet, während die anderen beiden Ausdrücke bei jedem Schleifendurchlauf ausgewertet werden • die for-Anweisung entspricht damit der folgenden Anweisungsfolge: Ausdruck_1; while (Ausdruck_2) { Anweisungsblock; Ausdruck_3; }; Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C • Folie 4 - 7 alle drei Ausdrücke können entfallen; die ';' müssen aber stehen bleiben • Beispiele: 1) for (i = 0; i < 10; ++i) { printf ("%d zum Quadrat: %ld\n", i, i * i); }; 2) for (;;) { ...; }; /* Endlosschleife */ 3) for (; x < y;) { ...; }; /* while-Schleife */ 4) for (i = 0; i < 32000; ++i) { ; /* Warteschleife }; */ 5) for (c = getchar (); isspace (c); c = getchar ()) { ; /* white-space überlesen */ }; ungetc (c, stdin); /* c!=' ' zurück in Puffer*/ • Bemerkungen: 1) der Wert einer Schleifenvariablen kann im Schleifenkörper verändert werden 2) der letzte Wert der Schleifenvariablen ist nach dem Verlassen der Schleife außerhalb der Schleife bekannt Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C Folie 4 - 8 3) eine Null-Anweisung wie in Beispiel 4 oder 5 sollte immer auf einer eigenen Zeile stehen, damit das Programm lesbarer ist 4) speziell in for-Anweisungen findet der Komma-Operator seine Anwendung (Eine Folge von Anweisungen, die durch den Komma-Operator getrennt sind, wird von links nach rechts abgearbeitet. Typ und Wert der Anweisungsfolge werden durch Typ und Wert der letzten Anweisung (rechter Operand) bestimmt. Der KommaOperator ist von den Kommata in Deklarationen, Parametern bei Funktionen usw. zu unterscheiden, die keine bestimmte Auswertungsreihenfolge garantieren) Beispiel: void reverse (char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) { c = s [i]; s [i] = s [j]; s [j] = c; }; }; ◊ Komma-Operatoren sollten möglichst selten verwendet werden und dann nur in solchen Fällen, in denen ein enger Zusammenhang zwischen den einzelnen Anweisungen besteht ◊ der Austausch der Zeichen in der obigen Routine könnte z.B. als zusammenhängende Operation gesehen werden und mit dem Komma-Operator folgendermaßen realisiert werden: c = s[i], s[i] = s[j], s[j] = c; Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C 4.5 • Folie 4 - 9 do-while-Anweisung Syntax: do { Anweisungsblock; } while (Ausdruck); • entspricht bis auf die Abbruchbedingung der repeat-until-Anweisung von Pascal, d.h. der Anweisungsblock wird mindestens einmal ausgeführt • eine repeat-until-Anweisung könnte mit den beiden folgenden Präprozessor-Anweisungen simuliert werden (im Rahmen dieser Lehrveranstaltung verboten ! ): #define REPEAT #define UNTIL(cond) • do { ;} while (!(cond)); Beispiel: do { c = getchar (); if (c == ' ') { n_of_spaces++; }; } while (c != '\n'); Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C 4.6 • Folie 4 - 10 break-Anweisung Syntax: break; • Einsatz: 1) bei switch-Anweisung: Trennung der einzelnen Alternativen 2) bei for-, while-, do-while-Anweisung: vorzeitiger Abbruch der innersten Schleife (unabhängig von der Bedingung) • Beispiel (' ', '\t' und '\n' am Ende einer Zeichenfolge entfernen): int trim (char s[]) { int n; for (n = strlen(s) - 1; n >= 0; --n) { if (s [n] != ' ' && s [n] != '\t' && s [n] != '\n') { break; }; }; s [n+1] = '\0'; }; Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C 4.7 • Folie 4 - 11 continue-Anweisung Syntax: continue; • wird nur bei for-, while-, do-while-Anweisungen verwendet • bewirkt, daß sofort die nächste Iteration der innersten Schleife begonnen wird • Beispiel (nur nicht-negative Zahlen eines Feldes bearbeiten): for (i = 0; i < n; ++i) { if (a[i] < 0) { continue; }; ...; /* nur positive Zahlen */ }; 4.8 • return-Anweisung Syntax: return Ausdruck; • Rückgabe eines Wertes in einer Funktion • mehrere Werte können z.B. mit Hilfe eines Zeigers auf eine Struktur zurückgegeben werden Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C • Folie 4 - 12 mit Ausnahme von Feldern und Funktionen kann jeder Wert zurückgegeben werden (z.B. auch vollständige Strukturen; dies ist allerdings sehr ineffizient) • der Rückgabewert kann optional in runde Klammern eingeschlossen werden (wird i.a. bei komplizierten Ausdrücken zur besseren Lesbarkeit verwendet) • eine Funktion kann beliebig viele return-Anweisungen enthalten. In diesem Fall wird die erste return-Anweisung ausgeführt, die im normalen Datenfluß erreicht wird. • falls eine Funktion keine return-Anweisung enthält, erfolgt die Rückkehr aus der Funktion, sobald die schließende geschweifte Klammer der Funktion erreicht wird. Der Rückgabewert ist in diesem Fall undefiniert. • der Rückgabewert ist ebenfalls undefiniert, falls der return-Anweisung kein Ausdruck folgt • der Rückgabewert muß mit dem Typ der Funktion kompatibel sein, d.h. entweder mit ihm übereinstimmen oder in ihn konvertierbar sein Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß S. d. I.: Programieren in C 4.9 • Folie 4 - 13 goto-Anweisung Syntax: goto marke; • wird normalerweise nicht benötigt • hilfreich, falls eine tief verschachtelte Programmstruktur beendet werden soll, z.B. Abbruch von mehr als zwei Schleifen auf einmal (break ist hier nicht geeignet, da es nur die innerste Schleife beenden würde) • Sprungziele (Marken) haben die gleiche Form wie eine Variable und enden mit einem Doppelpunkt • goto darf nur dann verwendet werden, wenn dafür sehr gute Gründe vorliegen, da solche Programme schwer les- und wartbar sind • Beispiel: for (...) for (...) for (...) { ...; if (...) { goto fehler; }; ...; }; ...; fehler:... Fachhochschule Fulda, Fachbereich AI, Prof. Dr. S. Groß