Instrukcja wyboru (ang. switch statement) w zasadzie zawsze może być zastąpiona instrukcjami warunkowymi, ale czasem czytelniej jest użyć właśnie instrukcji wyboru. Jej najbardziej ogólna postać to:
switch (wyr_calk) { case stala1: lista1 case stala2: lista2 // ... dafault: lista }gdzie wyr_calk jest wyrażeniem o wartości całkowitej, stala1, stala2, ..., są wyrażeniami stałymi o wartości całkowitej, a lista1, lista2, ..., są listami instrukcji (być może pustymi). Wyrażeniem stałym całkowitym może być tu liczba podana w postaci literału, nazwa całkowitej zmiennej ustalonej lub wyrażenie całkowite składające się z tego typu podwyrażeń. Liczba fraz case może być dowolna. Stałe występujące w każdej z fraz case muszą być różne. Listy instrukcji mogą też być puste. Fraza default jest opcjonalna: jeśli występuje, to może wystąpić tylko raz, choć niekoniecznie na końcu.
Najpierw obliczane jest wyr_calk. Następnie, jeśli obliczona wartość jest równa wartości którejś ze stałych stala1, stala2, ..., to wykonywane są instrukcje ze wszystkich list instrukcji, poczynając od listy we frazie case odpowiadającej tej stałej. A więc wykonywane są nie tylko instrukcje z listy w znalezionej frazie case, ale również ze wszystkich dalszych list!
Jeśli żadna ze stałych stala1, stala2, ..., nie jest równa wartości wyr_calk, a fraza default istnieje, to wykonywane są wszystkie instrukcje poczynając od tych we frazie default. Jeśli natomiast żadna ze stałych stala1, stala2, ..., nie jest równa wyr_calk, a fraza default nie istnieje, to wykonanie całej instrukcji wyboru uznaje się za zakończone.
Dowolną z instrukcji może być instrukcja zaniechania break. Jeśli sterowanie przejdzie przez tę instrukcję, to wykonanie całej instrukcji wyboru kończy się.
Instrukcję wyboru zilustrowano w poniższym programie; funkcja
sw
powoduje wypisanie różnej liczby gwiazdek w zależności
od wartości argumentu: cztery gwiazdki dla argumentu 1, dwie dla
argumentu 5, zero dla argumentu 2 lub 3 i trzy gwiazdki dla każdej
innej wartości argumentu.
1. #include <iostream> 2. using namespace std; 3. 4. void g( ) { 5. cout << '*'; 6. } 7. 8. void sw(int k) { 9. cout << k << ": "; 10. switch ( k ) { 11. default: g( ); ➊ 12. case 5: g( ); g( ); ➋ 13. case 3: 14. case 2: break; ➌ 15. case 1: g( ); g( ); g( ); g( ); 16. } 17. cout << endl; 18. } 19. 20. int main() { 21. sw(9); 22. sw(5); 23. sw(4); 24. sw(3); 25. sw(2); 26. sw(1); 27. sw(0); 28. }
Działanie programu widać z wyników
9: *** 5: ** 4: *** 3: 2: 1: **** 0: ***Zauważmy, że dla argumentów różnych od 1, 2, 3, 5 sterowanie przechodzi do instrukcji występującej we frazie default (linia ➊) i przechodzi następnie do instrukcji we frazach case odpowiadających wartościom 5, 3 i 2. Dopiero w linii ➌ napotykana jest instrukcja break, która kończy wykonywanie całej instrukcji wyboru. Dlatego drukowane są wtedy trzy gwiazdki: jedna w linii ➊ i dwie w linii ➋ programu.
Fraza default wcale nie musi, jak widać z programu, występować na końcu.
Jeśli jedną z instrukcji jest instrukcja
return, to
przejście przez nią sterowania spowoduje oczywiście również
zakończenie wykonywania instrukcji wyboru i zakończenie
wykonywania funkcji w której występuje. Funkcja
hexVal
w poniższym programie wyznacza wartość liczbową odpowiadającą
cyfrze szesnastkowej podanej w postaci znaku lub dostarcza -1, jeśli
podany znak nie odpowiada żadnej cyfrze szesnastkowej:
1. #include <iostream> 2. using namespace std; 3. 4. int hexVal(char c) { 5. switch ( c ) { 6. case '0': case '1': case '2': ➊ 7. case '3': case '4': case '5': 8. case '6': case '7': case '8': 9. case '9': 10. return c - '0'; ➋ 11. 12. case 'a': case 'b': case 'c': 13. case 'd': case 'e': 14. case 'f': 15. return 10 + c - 'a'; ➌ 16. 17. case 'A': case 'B': case 'C': 18. case 'D': case 'E': 19. case 'F': 20. return 10 + c - 'A'; ➍ 21. 22. default: return -1; ➎ 23. } 24. } 25. 26. int main() { 27. cout << "A = " << hexVal('A') << endl 28. << "f = " << hexVal('f') << endl 29. << "9 = " << hexVal('9') << endl 30. << "b = " << hexVal('b') << endl 31. << "Z = " << hexVal('Z') << endl; 32. }
W linii ➊ i trzech następnych zgrupowanych jest wiele fraz case pustych, z wyjątkiem ostatniej, która zawiera instrukcję return. Dzięki temu zawsze, gdy argumentem funkcji jest znak odpowiadający którejś z cyfr, sterowanie dojdzie do linii ➋ zwracając właściwą wartość (bo liczbowo zmienna c ma wartość kodu ASCII odpowiedniej cyfry; odejmując kod ASCII znaku '0' otrzymamy wartość liczbową znaku c). Podobnie dla dowolnej małej litery odpowiadającej którejś z cyfr szesnastkowych sterowanie dojdzie do linii ➌, a dla dużej litery — do linii ➍. Jeśli znak nie odpowiada żadnej cyfrze szesnastkowej, wejdziemy do frazy default i zwrócona zostanie w linii ➎ wartość -1. Wynik tego programu:
A = 10 f = 15 9 = 9 b = 11 Z = -1
T.R. Werner, 21 lutego 2016; 20:17