5.5 Mehrfache Verzweigung mit switch
In C finden Sie noch eine zweite Möglichkeit einer mehrfachen Verzweigung in Form der Fallunterscheidung mit switch. switch können Sie für die Auswertung eines ganzzahligen Ausdrucks verwenden. Die Ausdrücke zum Auswerten müssen char-, int- oder long-Werte sein. Die Syntax hierzu sieht folgendermaßen aus:
switch(Ausdruck) {
case Ausdruck1: anweisungen1; break;
case Ausdruck2: anweisungen2; break;
case Ausdruck3: anweisungen3; break;
…
case AusdruckN: anweisungenN; break;
default: anweisungen;
}
Mit switch wird hier der ganzzahlige Ausdruck bewertet und mit den ganzzahligen Konstanten der folgenden case-Marken verglichen. Stimmt eine dieser case-Marken mit der switch-Auswertung von Ausdruck überein, wird die Programmausführung hinter dieser case-Marke fortgeführt. Stimmt keine case-Marke mit der switch-Auswertung überein, kann optional eine default-Marke verwendet werden. Diese wird dann auf jeden Fall ausgeführt.
Hierzu ein vereinfachter Programmablaufplan einer solchen switch-Fallunterscheidung:
Folgendes Beispiel soll Ihnen die switch-Fallunterscheidung näherbringen:
00 // Kapitel5/switch_case_1.c
01 #include <stdio.h>
02 int main(void) {
03 int eingabe = 0;
04 printf("-1- Level 1\n");
05 printf("-2- Level 2\n");
06 printf("-3- Level 3\n");
07 printf("-4- Beenden\n");
08 printf("Ihre Auswahl bitte: ");
09 int check = scanf("%d", &eingabe);
10 if( check != 1) {
11 printf("Fehler bei der Eingabe ...\n");
12 return 1;
13 }
14 switch(eingabe) {
15 case 1 : printf("Level 1 war die Auswahl\n");
16 break;
17 case 2 : printf("Level 2 war die Auswahl\n");
18 break;
19 case 3 : printf("Level 3 war die Auswahl\n");
20 break;
21 case 4 : printf("Beenden war die Auswahl\n");
22 break;
23 default : printf("%d? Unbekannter Level!\n", eingabe);
24 }
25 return 0;
26 }
In diesem Beispiel werden Sie in einer Art Menü aufgefordert, eine Zahl von 1 bis 4 einzugeben. In Zeile (14) wird dieser Ausdruck in der switch-Anweisung überprüft und im switch-Rumpf (Zeile (15) bis (24)) mit den case-Marken verglichen. Je nachdem, welche case-Marke zutrifft – hier 1, 2, 3 oder 4 –, werden die darauffolgenden Anweisungen ausgeführt. Haben Sie beispielsweise den ganzzahligen Wert 2 eingegeben, wird die Programmausführung mit der case-Marke 2 (Zeile (17)) fortgeführt. Das bedeutet im konkreten Fall, dass alle Anweisungen hinter dem Doppelpunkt dieser case-Marke bis zum nächsten break ausgeführt werden. Wurde ein anderer Wert als 1, 2, 3 oder 4 eingegeben, werden die Anweisungen der alternativen (aber optionalen) default-Anweisung (Zeile (23)) ausgeführt.
Das Programm gibt bei der Ausführung folgendes Menü aus:
-1- Level 1
-2- Level 2
-3- Level 3
-4- Beenden
Ihre Auswahl bitte: 3
Level 3 war die Auswahl
-1- Level 1
-2- Level 2
-3- Level 3
-4- Beenden
Ihre Auswahl bitte: 99
99? Unbekannter Level!
5.5.1 Austritt aus der Fallunterscheidung mit break
Von besonderer Wichtigkeit bei der switch-Fallunterscheidung sind die break-Anweisungen am Ende einer case-Marke. Mit diesem break weisen Sie das Programm an, aus dem switch-Rumpf herauszuspringen und mit der Programmausführung dahinter fortzufahren. Verwenden Sie nach einer case-Marke keine break-Anweisung, werden alle weiteren Anweisungen (auch die der nächsten case-Marken) im switch-Rumpf bis zum nächsten break oder bis zum Ende des Rumpfes ausgeführt.
Dies bewirkt break in einer switch-Fallunterscheidung
Dank eines break an letzter Stelle einer case-Marke ist es möglich, ohne geschweifte Klammern in case-Blöcken auszukommen. Ohne einen break werden alle folgenden case-Anweisungen unabhängig von den Bedingungen ausgeführt.
Das absichtliche Weglassen von break kann allerdings durchaus gewollt sein, wie das folgende Beispiel demonstriert:
00 // Kapitel5/switch_case_2.c
01 #include <stdio.h>
02 int main(void) {
03 int opt = 0;
04 printf("-1- Option A\n");
05 printf("-2- Option B\n");
06 printf("-3- Option C\n");
07 printf("-4- Option D\n");
08 printf("Ihre Auswahl: ");
09 int check = scanf("%d", &opt);
10 if(check != 1) {
11 printf("Fehler bei der Eingabe ...\n");
12 return 1;
13 }
14 switch(opt) {
15 case 1 : printf("Option A beinhaltet auch ");
16 case 2 : printf("Option B\n");
17 break;
18 case 3 :
19 case 4 : printf("Option C und D sind gleich\n");
20 break;
21 default : printf("Unbekannte Option (%d)?\n" , opt);
22 }
23 return 0;
24 }
In Listing 5.6 wurde nach der Anweisung in Zeile (15) kein break verwendet. Falls nun der Wert 1 eingegeben wird, wird neben der case-Marke für 1 auch gleich die case-Marke für 2 aus Zeile (16) ausgeführt. Es wird hier einfach davon ausgegangen, dass für die Funktion mit der Option A zusätzlich noch die Funktion mit der Option B benötigt wird. Wird hingegen nur mit dem Wert 2 die Option B gewählt, werden nur die Anweisungen hinter der case-Marke von 2 (Zeilen (16) und (17)) ausgeführt. Zu den Funktionen der case-Marke 1 mit der Option A wird dabei nicht verzweigt.
In den Zeilen (18) und (19) wurde Ähnliches gemacht. Die leere case-Marke mit dem Wert 3 ohne break dient dazu, zusätzlich noch den Wert 4 zuzulassen. Es werden also in diesem Fall immer die Anweisungen der Zeilen (19) und (20) zusammen ausgeführt.
Das Programm gibt bei der Ausführung folgendes Menü aus:
-1- Option A
-2- Option B
-3- Option C
-4- Option D
Ihre Auswahl: 1
Option A beinhaltet auch Option B
-1- Option A
-2- Option B
-3- Option C
-4- Option D
Ihre Auswahl: 2
Option B
-1- Option A
-2- Option B
-3- Option C
-4- Option D
Ihre Auswahl: 3
Option C und D sind gleich
-1- Option A
-2- Option B
-3- Option C
-4- Option D
Ihre Auswahl: 4
Option C und D sind gleich
Natürlich sollte nicht unerwähnt bleiben, dass Sie anstatt einer switch-Fallunterscheidung auch bedingte if-Anweisungen mit else-if-Verzweigungen für das letzte Beispiel verwenden können. Wann Sie mehrfache Alternativen mit switch oder mit else if erstellen sollten und wann nicht, hängt natürlich auch vom Anwendungsfall ab.
Sie sollten allerdings zum Schluss noch Folgendes bedenken: switch funktioniert wie if, und ist deshalb sehr langsam! Wenn Sie auf die hier dargestellte Weise 100 Bedingungen »durcheiern« müssen, wird die Performance Ihres Programms sehr leiden. Ferner ist es stark vom Compiler abhängig, wie switch umgesetzt wird. Meistens wird switch einfach in if-Anweisungen umgewandelt, und diese müssen alle durchlaufen werden. Dabei gibt es den sogenannten Best Case (bester Fall), der dann eintritt, wenn schon die erste Bedingung erfüllt ist. Der sogenannte Worst Case (schlechtester Fall) tritt ein, wenn erst die letzte Bedingung erfüllt ist. Genau an dieser Stelle leidet dann die Performance.