C++-Programmierung/ Einführung in C++/ Auswahl
Verzweigungen kennen Sie schon, daher sollte es Ihnen nicht schwer fallen, ein Programm zu schreiben, welches abfragt, welche der verschiedenen, in der Überschrift benannten Leckereien, Sie am liebsten mögen. Das ganze könnte etwa so aussehen:
1#include <iostream>
2
3using namespace std;
4
5int main(){
6 int auswahl;
7
8 cout << "Wählen Sie Ihre Lieblingsleckerei:\n"
9 "1 - Käsesahnetorte\n"
10 "2 - Streuselkuchen\n"
11 "3 - Windbeutel\n";
12
13 cin >> auswahl;
14
15 if(auswahl==1)
16 cout << "Sie mögen also Käsesahnetorte!\n";
17 else if(auswahl==2)
18 cout << "Streuselkuchen ist ja auch lecker...\n";
19 else if(auswahl==3)
20 cout << "Windbeutel sind so flüchtig wie ihr Name, das können Sie sicher bestätigen?\n";
21 else
22 cout << "Wollen Sie wirklich behaupten, dass Ihnen nichts davon zusagt?\n";
23
24 return 0;
25}
1Wählen Sie Ihre Lieblingsleckerei:
21 - Käsesahnetorte
32 - Streuselkuchen
43 - Windbeutel
5<Eingabe>2</Eingabe>
6Streuselkuchen ist ja auch lecker...
Das funktioniert natürlich, aber finden Sie nicht auch, dass der (Schreib-)Aufwand ein wenig zu groß ist? Außerdem ist diese Schreibweise nicht gerade sofort einleuchtend. Für unseren Fall, wäre es schöner, wenn wir die Variable
auswahl
als zu untersuchendes Objekt festlegen könnten und dann einfach alle Fälle die uns interessieren durchgehen könnten. Praktischerweise bietet C++ ein Schlüsselwort, das genau dies ermöglicht.
switch
und break
[Bearbeiten]
switch
break
Eine
switch
-Anweisung hat die folgende Form:
switch(«Ganzzahlige Variable»){
case «Ganzzahl»: «Anweisungsblock»
case «Ganzzahl»: «Anweisungsblock»
«...»
default: «Anweisungsblock»
}
Auf unser Beispiel angewandt, würde das dann so aussehen:
1#include <iostream>
2
3using namespace std;
4
5int main(){
6 int auswahl;
7
8 cout << "Wählen Sie Ihre Lieblingsleckerei:\n"
9 "1 - Käsesahnetorte\n"
10 "2 - Streuselkuchen\n"
11 "3 - Windbeutel\n";
12
13 cin >> auswahl;
14
15 switch(auswahl){
16 case 1: cout << "Sie mögen also Käsesahnetorte!";
17 case 2: cout << "Streuselkuchen ist ja auch lecker...";
18 case 3: cout << "Windbeutel sind so flüchtig wie ihr Name, das können Sie sicher bestätigen?";
19 default: cout << "Wollen Sie wirklich behaupten, dass Ihnen nichts davon zusagt?";
20 }
21
22 return 0;
23}
1Wählen Sie Ihre Lieblingsleckerei:
21 - Käsesahnetorte
32 - Streuselkuchen
43 - Windbeutel
5<Eingabe>2</Eingabe>
6Streuselkuchen ist ja auch lecker...
7Windbeutel sind so flüchtig wie ihr Name, das können Sie sicher bestätigen?
8Wollen Sie wirklich behaupten, dass Ihnen nichts davon zusagt?
Nun ja, Sie haben ein neues Schlüsselwort kennen gelernt, setzen es ein und kommen damit auch prompt zum falschen Ergebnis. Sieht so aus, als würde jetzt jeder der Sätze ab dem Ausgewählten ausgegeben. In der Tat handelt
switch
genau so. Es führt alle Anweisungen, ab dem Punkt aus, an dem das
case
-Argument mit der übergebenen Variable (in unserem Fall
auswahl
) übereinstimmt. Um das Ausführen nachfolgender Anweisungen innerhalb von
switch
zu verhindern, benutzen Sie das Schlüsselwort
break
. Unser Beispiel sieht dann also folgendermaßen aus:
1#include <iostream>
2
3using namespace std;
4
5int main(){
6 int auswahl;
7
8 cout << "Wählen Sie Ihre Lieblingsleckerei:\n"
9 "1 - Käsesahnetorte\n"
10 "2 - Streuselkuchen\n"
11 "3 - Windbeutel\n";
12
13 cin >> auswahl;
14
15 switch(auswahl){
16 case 1:
17 cout << "Sie mögen also Käsesahnetorte!";
18 break;
19 case 2:
20 cout << "Streuselkuchen ist ja auch lecker...";
21 break;
22 case 3:
23 cout << "Windbeutel sind so flüchtig wie ihr Name, das können Sie sicher bestätigen?";
24 break;
25 default:
26 cout << "Wollen Sie wirklich behaupten, dass Ihnen nichts davon zusagt?";
27 }
28
29 return 0;
30}
1Wählen Sie Ihre Lieblingsleckerei:
21 - Käsesahnetorte
32 - Streuselkuchen
43 - Windbeutel
5<Eingabe>2</Eingabe>
6Streuselkuchen ist ja auch lecker...
Nun haben Sie wieder das ursprüngliche, gewünschte Verhalten. Was Sie noch nicht haben, ist eine Erklärung, warum extra ein
break
aufgerufen werden muss, um das Ausführen folgender
case
-Zweige zu unterbinden. Aber das werden Sie gleich erfahren.
Nur Ganzzahlen[Bearbeiten]
Wie bereits aus der oben stehenden Syntaxangabe hervorgeht, kann
switch
nur mit Ganzzahlen benutzt werden. Dies hängt damit zusammen, dass
switch
ausschließlich auf Gleichheit mit einem der
case
-Zweige vergleicht. Bei
int
-Werten (mit der üblichen Größe von 4 Byte) ist das noch eine „überschaubare“ Menge von maximal 4.294.967.296 ()
case
-Zweigen. Ein
float
kann die gleiche Menge unterschiedlicher Zahlen darstellen, sofern er ebenfalls 4 Byte groß ist. Aber versuchen Sie mal einen genauen
float
-Wert aufzuschreiben. Sie arbeiten also immer mit Näherungen, wenn Sie Gleitkommazahlen in Ihrem Code benutzen. Ihr Compiler regelt das für Sie, er weist der Gleitkommazahl den zu Ihrem Wert am nächsten liegenden, darstellbaren Wert zu. Deshalb ist es so gut wie nie sinnvoll (aber natürlich trotzdem möglich), einen Test auf Gleichheit für Gleitkommazahlen durchzuführen. Bei
switch
wurde das jedoch unterbunden.
Zeichen und mehrere case
-Zweige[Bearbeiten]
case
Eine
if
-Anweisung trifft Ihre Entscheidung hingegen, anhand der Tatsache ob eine Bedingung erfüllt ist, oder nicht. Für die
if
-Anweisung gibt es also nur zwei Möglichkeiten. Allerdings gibt es eine ganze Menge von Möglichkeiten, wie der Zustand
true
, oder
false
erreicht werden kann. Die Rede ist von Vergleichen und Verknüpfungen ( wie
&&
(= und) oder
||
(= oder) ) und der Umwandlung von anderen Datentypen nach
true
, oder
false
. Für ganzzahlige Datentypen gilt etwa, dass jeder Wert ungleich 0
true
ergibt, aber 0 hingegen wird als
false
ausgewertet. Für eine genaue Beschreibung dessen, was hier noch mal kurz umrissen wurde, sehen Sie sich das Kapitel über Verzweigungen an. Also gut,
switch
kann nur auf Gleichheit testen und erlaubt auch keine Verknüpfungen. Oder sagen wir besser: fast keine. Denn genau deshalb gibt es diese scheinbar aufwendige Regelung mit dem
break
. Das folgende Beispiel demonstriert die Verwendung von Zeichen und die Anwendung von mehreren
case
-Zweigen, die den gleichen Code ausführen (was einer Verknüpfung mit
||
zwischen mehreren Vergleichen mittels
==
gleichkommt):
1#include <iostream>
2
3using namespace std;
4
5int main(){
6 char auswahl;
7
8 cout << "Wählen Sie Ihre Lieblingsleckerei:\n"
9 "K - Käsesahnetorte\n"
10 "S - Streuselkuchen\n"
11 "W - Windbeutel\n";
12
13 cin >> auswahl;
14
15 switch(auswahl){
16 case 'k':
17 case 'K':
18 cout << "Sie mögen also Käsesahnetorte!";
19 break;
20 case 's':
21 case 'S':
22 cout << "Streuselkuchen ist ja auch lecker...";
23 break;
24 case 'w':
25 case 'W':
26 cout << "Windbeutel sind so flüchtig wie ihr Name, das können Sie sicher bestätigen?";
27 break;
28 default:
29 cout << "Wollen Sie wirklich behaupten, dass Ihnen nichts davon zusagt?";
30 }
31
32 return 0;
33}
1Wählen Sie Ihre Lieblingsleckerei:
2K - Käsesahnetorte
3S - Streuselkuchen
4W - Windbeutel
5<Eingabe>s</Eingabe>
6Streuselkuchen ist ja auch lecker...
Dieses Programm benutzt die Anfangsbuchstaben anstatt der bisherigen Durchnummerierung für die Auswahl. Außerdem ist es möglich sowohl den großen, als auch den kleinen Buchstaben einzugeben. Beides führt den gleichen Code aus.
Missing 'break'[Bearbeiten]
Da
switch
„von oben nach unten“ abgearbeitet wird, benötigt der letzte Fall kein 'break' - dort endet die Switch-Struktur sowieso. Es ist jedoch erlaubt, den 'default'-Fall auch vor einem oder mehreren 'case'-Fällen aufzuführen - dann sollte er ebenso mit einer 'break'-Anweisung enden, wie jeder andere Fall.
Der letzte Fall darf ebenso mit 'break' enden, wie alle anderen - es schadet nicht ;-)