5.4    Die mehrfache Verzweigung mit if und else if

Reicht Ihnen eine bedingte if-Anweisung nicht aus, können Sie mehrere bedingte if-Anweisungen hintereinander anordnen. Hierzu fügen Sie nach der ersten bedingten if-Anweisung der Reihe nach weitere bedingte else-if-Anweisungen an. Die Syntax sieht dann folgendermaßen aus:

if(ausdruck1) {
anweisung1;
}
else if (ausdruck2) {
anweisung2;
}
// Weitere else-if-Anweisungen möglich
anweisung3;

Zuerst wird die Bedingung ausdruck1 ausgewertet. Wenn die Bedingung in ausdruck1 wahr (ungleich 0) ist, wird die Anweisung anweisung1 im Anweisungsblock ausgeführt. Anschließend wird die Programmausführung mit der Anweisung anweisung3 fortgesetzt. Ist die Bedingung ausdruck1 allerdings unwahr (also gleich 0), fährt das Programm der Reihe nach mit der nächsten Überprüfung der Bedingung ausdruck2 fort. Ist die Bedingung ausdruck2 wahr (ungleich 0), wird die Anweisung anweisung2 ausgeführt. Anschließend fährt das Programm mit der Anweisung anweisung3 fort.

Abbildung 5.3 stellt diese zusätzliche else-if-Anweisung in einem Programmablaufplan schematisch dar.

Programmablaufplan mit einer else if-Verzweigung

Abbildung 5.3    Programmablaufplan mit einer else if-Verzweigung

Natürlich ist es auch möglich, mehrere bedingte else-if-Anweisungen zu verwenden. Optional können Sie am Ende auch noch eine alternative else-Verzweigung hinzufügen. Hierzu ein Beispiel:

if(ausdruck1) {
anweisung1;
}
else if (ausdruck2 ) {
anweisung2;
}
else if (ausdruck3) {
anweisung3;
}
// Weitere else-if-Verzweigungen möglich
else {
anweisung4;
}
...

Das folgende Listing zeigt eine solche else-if-Kette in der Praxis:

00  // Kapitel5/elseif_beispiel.c
01 #include <stdio.h>

02 int main(void) {
03 int ival = 0;
04 printf("Bitte eine positive Ganzzahl eingeben: ");
05 int check = scanf("%d", &ival);
06 if( check != 1 ) {
07 printf("Fehler bei der Eingabe!\n");
08 }
09 else if(ival <= 0) {
10 printf("Keine negativen Werte oder 0 verwenden\n");
11 }
12 else {
13 printf("Ihre Eingabe: %d\n", ival);
14 }
15 printf("Außerhalb der if-Verzweigung\n");
16 return 0;
17 }

Listing 5.3    Das elseif_beispiel.c demonstriert die Verwendung von else if.

Das letzte Listing kennen Sie ja bereits in einer ähnlichen Form. Diesmal wurde allerdings gleich in der ersten bedingten if-Anweisung in Zeile (06) überprüft, ob auch ein gültiger Wert mit scanf(), passend zum Umwandlungszeichen, eingegeben wurde. Wenn der Rückgabewert von scanf() hier nicht 1 war, brauchen Sie gar nicht mehr weiterzumachen, weshalb hier gleich eine Fehlermeldung in Zeile (07) ausgegeben wird.

Wurde ein gültiger Wert eingegeben, prüfen Sie in Zeile (09) mit der nächsten bedingten else-if-Anweisung den Inhalt von ival, also ob der Wert kleiner oder gleich 0 ist. Ist diese Bedingung wahr (ungleich 0), machen Sie nicht mehr weiter, weil Sie einen positiven Wert und auch keine 0 erhalten wollen. In diesem Fall geben Sie die entsprechende Meldung in Zeile (10) aus.

Wenn keine der mehrfach bedingten Verzweigungen ausgeführt wird, kann nur noch die else-Verzweigung in den Zeilen (12) bis (14) ausgeführt werden. In dem Fall ist der eingegebene Wert gültig und wird in Zeile (13) ausgegeben.

Das Programm gibt bei der Ausführung z. B. Folgendes aus:

Bitte eine positive Ganzzahl eingeben: 123
Ihre Eingabe: 123
Außerhalb der if-Verzweigung

Bitte eine positive Ganzzahl eingeben: x
Fehler bei der Eingabe!
Außerhalb der if-Verzweigung

Bitte eine positive Ganzzahl eingeben: -77
Keine negativen Werte oder 0 verwenden
Außerhalb der if-Verzweigung

5.4.1    Verschachteln von Verzweigungen

Es ist natürlich auch möglich, Verzweigungen zu verschachteln. Je nach Situation können Sie hiermit das Programm verkürzen oder die Logik vereinfachen. Sie können aber leider auch das Gegenteil erreichen und unübersichtlichen Code erzeugen. Das folgende verschachtelte Beispiel, das dieselbe Funktionalität hat wie das Listing 5.3, demonstriert dies:

00  // Kapitel5/verschachteltes_if.c
01 #include <stdio.h>

02 int main(void) {
03 int ival = 0;
04 printf("Bitte eine positive Ganzzahl eingeben: ");
05 int check = scanf("%d", &ival);
06 if( check == 1 ) {
07 if(ival <= 0) {
08 printf("Keine negativen Werte oder 0 verwenden\n");
09 }
10 else {
11 printf("Ihre Eingabe: %d\n", ival);
12 }
13 }
14 else {
15 printf("Fehler bei der Eingabe!\n");
16 }
17 printf("Außerhalb der if-Verzweigung\n");
18 return 0;
19 }

Listing 5.4    Das letzte Beispiel verwendet verschachtelte if-Verzweigungen.

Zwar ist der logische Ablauf des Programms etwas anders als beim Listing 5.3 zuvor, aber das Endergebnis ist dasselbe. Zunächst wird in Zeile (06) überprüft, ob der von scanf() zurückgegeben Wert gleich 1 ist. Ist dies nicht der Fall, gibt der Ausdruck 0 zurück, und es kann gleich die alternative else-Anweisung in den Zeilen (14) bis (16) ausgeführt werden, weil ein Fehler bei der Eingabe aufgetreten ist. Wurde ein korrekter Wert mit scanf() eingelesen, wird in der verschachtelten Verzweigung in (07) bis (12) der eingegebene Wert überprüft und ausgegeben, wenn kein negativer Wert oder 0 eingegeben wurde.

if-Verzweigungen ohne Anweisungsblock

Besitzt eine bedingte if-Anweisung, eine else-Verzweigung oder eine bedingte else-if-Verzweigung nur eine Anweisung, können Sie den Anweisungsblock mit { ... } auch weglassen. Ein Anweisungsblock ist nur dann unbedingt nötig, wenn mehrere Anweisungen zu einem Block zusammengefasst werden müssen.

Sie sollten ein zu tiefes Verschachteln von Anweisungsblöcken nach Möglichkeit vermeiden und nach Möglichkeit lieber geklammerte logische Ausdrücke verwenden, z. B. if ((a==1)||(b==1) { } Auf logische Ausdrücke werden wir in Kürze eingehen. Wir selbst ziehen diese zur Not geklammerten logischen Ausdrücke geschachtelten if-Anweisungen vor. In der Regel können Sie Verschachtelungen oft auch dadurch umgehen, dass Sie das Design des Codes etwas überdenken. Im Zweifelsfall sollten Sie sich immer für den leichter lesbaren Code entscheiden.

Zwar gibt es keine Regeln, wie Sie Anweisungsblöcke anordnen, wir empfehlen Ihnen aber, unbedingt eine saubere Formatierung wie beispielsweise gleichmäßige Einrückungen zu verwenden. Wenn Sie nicht umhinkommen, Anweisungsblöcke zu verschachteln, sind saubere Einrückungen (neben Kommentaren) ein Garant dafür, dass Sie den Code auch noch in ein paar Wochen lesen können.