#include #include /* C kennt folgende Anweisungen zur Flusskontrolle: Verzweigungskonstrukte: if ... else switch Schleifenkonstrukte: while do ... while for Spruenge: continue break return (im Zusammenhang mit Funktionen) goto Bei if-Bedingungen und Schleifenbedingungen benötigt man Vergleichs-Operatoren: == Abfrage auf Gleichheit. != Abfrage auf Ungleichheit < > <= "kleiner gleich" >= Logische Bedingungen können mit Booleschen Operatoren verknüpft werden: && AND || OR ! NOT ^ XOR */ int main() { int i = 9; int i_init; int i_div; int j; int counter; /* Die if-Bedingung ist ein beliebiger Ausdruck, der zu einem int-Wert ausgewertet werden kann. Insbesondere werden hier Ausdruecke ueber die Vergleichsoperatoren ==, !=, ... verwendet. Diese werten zu 0 aus, wenn der Vergleich nicht wahr ist, und zu 1 aus, wenn er wahr ist. Die Werte TRUE und FALSE gibt es nicht in C. */ if ( i < 9 ) { printf("i ist kleiner 9\n"); } else { /* else-Zweig (die Alternative): wird also durchlaufen, wenn if-Bedingung zu 0 auswertet. */ printf("i ist nicht kleiner 9\n"); } /* if-Bedingung mit int-Ausdruck */ if ( i - 8 ) { printf("i-8-Zweig genommen\n"); } else { printf("i-8-Zweig NICHT genommen\n"); } /* Die Booleschen Operatoren in C haben besondere Auswertungsregeln: (1) Die &&-Auswertung wird abgebrochen, sobald der erste Operand zu 0 auswertet. Das Ergebnis der &&-Auswertung ist dann 0. (2) Die ||-Auswertung bricht ab, sobald der erste Operand zu einem Wert != 0 auswertet. Das Ergebnis der ||-Auswertung ist dann 1. (3) !a hat den Wert 0, sobald a != 0 ist. Genau dann wenn a == 0, ist !a == 1. Da die Booleschen Operatoren in C immer auf Ausdrücken operieren, die zu ganzen Zahlen auswerten, darf man auch ZUWEISUNGEN in logischen Ausdrücken verwenden: Jede Zuweisung wertet zum Zuweisungsergebnis aus. Die goto-Anweisung fuehrt zu einem Sprung bis zu einem LABEL: goto mylabel; .... wird uebersprungen ... mylabel: ... ab hier geht es weiter ... */ i = 9; /* die illegale Zuweisung j = 15/0 wird gar nicht ausgefuehrt, weil i != 9 zu 0 auswertet, daher wird der 2. Operand von && gar nicht ausgewertet.*/ if ( i != 9 && (j = 15/0) ) printf("i == %d und j == %d\n",i,j); /* Die goto-Anweisung fuehrt zu einem Sprung bis zu der Marke (engl LABEL), die im goto referenziert wird. Die Marke wird im Code mit : angegeben.*/ goto jump_over_exit; exit (0); /* dies wird uebersprungen */ jump_over_exit: /* dies ist die Marke */ printf("Hier nach dem jump\n"); /* dagegen erhält man mit dem Vergleichsoperator == */ if ( i <= 9 && (j == 16) ) printf("i == %d und j == %d\n",i,j); else printf("else-Zweig: i == %d und j == %d\n",i,j); /* Die for-schleife führt einen Anweisungsblock so lange aus, bis eine Bedingung ueber einen Schleifenindex zu 0 auswertet. Der counter ist eine int-variable. counter = 0 ist die Initialisierung bei Schleifenbeginn. counter < 10 ist die Schleifenbedingung: solange diese != 0 auswertet, wird der Schleifenblock erneut durchlaufen. Die sogenannte Reinitialisierung, d.h. die Anweisung counter = counter + 2 wird immer bei Ende des Anweisungsblocks durchgefuehrt. */ for ( counter = 0; counter < 10; counter = counter + 2) { /* for-Anweisungsblock */ i = i + counter; printf(" counter = %d i = %d\n",counter,i); /* jetzt wird counter = counter + 2 ausgefuehrt. Dann wird counter < 10 ausgewertet Falls != 0, weiter bei i = i + counter. */ /* Die break-Anweisung fuehrt dazu, dass die nächste das break umschließende Schleife verlassen wird. */ if ( i == 9 ) { printf("Vorzeiges Verlassen der Schleife\n"); break; } /* die continue - Anweisung bewirkt einen Sprung an das Ende des Schleifenblocks */ if ( ! ( counter < 5 ) ) continue; printf("testausgabe1 %d\n",counter); printf("testausgabe2 %d\n",counter); } /* Schleifeninitialisierung, Schleifenbedingung und Reinitialisierung dürfen mehrere Anweisungen enthalten, die durch Komma separiert werden. */ for ( counter = 0, i = -100; counter < 10, i < -10; counter = counter + 2, i = i + counter, printf(" counter = %d i = %d\n",counter,i)) { } /* sind Schleifeninitialisierung, Schleifenbedingung und Reinitialisierung leer, erhält man eine Endlosschleife */ for ( ; ; ) { break; printf(" nimmt kein Ende ... "); printf(" abbrechen mit ^C\n"); sleep(1); } /* In einer while-Schleife wird der Schleifenkörper ausgeführt, solange die Schleifenbedingung wahr ist. Berechnung von i DIV j (ganzzahlige Division) und i modulo j (Divisionsrest). */ i_div = 0; i = i_init = 10; /* i und i_init wird jeweils 10 zugewiesen*/ j = 3; while ( i >= j ) { i = i - j; i_div++; /* erhoeht i_div um 1. i_div = i_div + 1 */ } printf(" %d DIV %d == %d und %d modulo %d == %d\n", i_init, j, i_div, i_init, j, i); /* in einer do-while-Schleife wird der Schleifenkörper mindestens einmal durchlaufen, denn die Schleifenbedingung wird erst am Ende ausgewertet. */ do { printf("in der do-while-Schleife\n"); } while ( i < -10 ); /* switch-Anweisung: Zuerst wird die switch-Bedingung ausgewertet. Hier also i. Dann wird in den case verzweigt, der den Wert der switch-Bedingung trägt. Endet der case-Zweig mit break; ist hiermit die Ausführung der switch-Anweisung beendet. Endet der case-Zweig NICHT mit break, werden die folgenden case-Zweige noch durchlaufen, bis der switch - Block beendet ist ODER ein break- Statement gefunden wird. Fuer jeden wert der Switch-Bedingung muss ein case gefunden werden - sonst knallts, manchmal, echt, ey! Mit dem default-Zweig werden alle Werte erfasst, die nicht mit case-Zweigen explizit angesprochen wurden. */ i = 100; switch ( i ) { case 1: case 100: printf("Operationen fuer Fall i == 1,100\n"); case 2 : printf("hier bin ich in case 2\n"); break; /* hier wird die switch-Anweisung verlassen*/ case 3 : printf("hier bin ich in case 3\n"); break; default: printf("hier bin ich im default-Zweig\n"); break; } printf("das äquivalente if: \n"); if ( i == 1 || i == 100 ) { printf("Operationen fuer Fall i == 1,100\n"); printf("hier bin ich in case 2\n"); } else if ( i == 2 ) { printf("hier bin ich in case 2\n"); } else if ( i == 3 ) { printf("hier bin ich in case 3\n"); } else { printf("hier bin ich im default-Zweig\n"); } }