In programmazione lo switch, chiamato a volte anche switch-case, è una struttura di controllo che permette la verifica del valore di un'espressione.
Si tratta di un'istruzione usata in gran parte dei linguaggi di programmazione, il cui ruolo consiste nel distinguere più casi corrispondenti ad altrettanti valori di un'espressione. Risulta utile quando si devono controllare tanti valori per una singola variabile, contesto dove spesso è molto efficiente, anche se questa affermazione dipende molto dal linguaggio, e quindi anche dalla implementazione usata.
Struttura generale
Un'espressione, per esempio una variabile, viene valutata e ne viene fatto un confronto di uguaglianza rispetto a valori definiti dal programmatore. Tali valori sono suddivisi in casi, che vengono specificati utilizzando la parola chiave case
. Se l'espressione ha un valore uguale a quello di uno dei casi previsti, viene eseguito il corrispondente codice. In molti linguaggi, i vari casi possono specificare solamente valori costanti, non variabili.[1][2]
I dettagli della sintassi variano in base al linguaggio usato, ma è possibile scrivere uno pseudocodice che dia un'idea generale:
SWITCH variabile
CASE '1': codice_1
CASE '2': codice_2
END
In genere, per poter "catturare" condizioni non previste nei vari case
, è inserito un caso predefinito default
che viene raggiunto se tutti i confronti si sono rivelati falsi.
SWITCH variabile
CASE '1': codice_1
CASE '2': codice_2
DEFAULT: raggiunto_se_condizioni_precedenti_non_vere
END
Esempi classici
Questi esempi sono relativi ad alcuni linguaggi con una sintassi simile al C: sebbene sia concettualmente la stessa struttura di controllo, altri linguaggi possono implementarla in modo molto diverso. Si veda il paragrafo successivo per approfondimenti.
Nei linguaggi C-like, come possono essere C++, C#, Java, PHP e lo stesso C, è necessario inserire l'istruzione break
prima di scrivere il successivo case
. In caso di mancanza, infatti, il flusso del controllo prosegue sequenzialmente con le istruzioni seguenti; in tal caso non viene eseguito solo il codice relativo alla condizione verificata, ma anche tutto il codice degli altri casi seguenti, fino al termine del costrutto switch-case
.
C++
#include <iostream>
using namespace std;
int main() {
int mese;
cout << "Inserisci il numero del mese" << endl;
cin >> mese;
switch(mese) {
case 1:
cout << "Gennaio" << endl;
break;
case 2:
cout << "Febbraio" << endl;
break;
case 3:
cout << "Marzo" << endl;
break;
case 4:
cout << "Aprile" << endl;
break;
case 5:
cout << "Maggio" << endl;
break;
case 6:
cout << "Giugno" << endl;
break;
case 7:
cout << "Luglio" << endl;
break;
case 8:
cout << "Agosto" << endl;
break;
case 9:
cout << "Settembre" << endl;
break;
case 10:
cout << "Ottobre" << endl;
break;
case 11:
cout << "Novembre" << endl;
break;
case 12:
cout << "Dicembre" << endl;
break;
default:
cout << "Puoi scegliere solo tra 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12." << endl;
}
return 0;
}
PHP
$numero = rand(1,3);
switch ($numero) {
case 1:
echo "Il numero uscito è 1";
break;
case 2:
echo "Il numero uscito è 2";
break;
case 3:
echo "Il numero uscito è 3";
break;
}
Implementazione in altri linguaggi
Pur essendo concettualmente la stessa struttura di controllo, il codice può cambiare di molto in base al linguaggio di riferimento, o può non esserci affatto una qualche implementazione. Alcuni linguaggi come ad esempio il Python, infatti, non contemplano affatto il costrutto switch-case
.
Citando altri esempi, il Perl lo ha introdotto dalla versione 5.10 con l'istruzione given
, o in alternativa tramite il modulo Switch scaricabile da CPAN.[3] Il linguaggio Ruby, per implementare questa struttura, si affida all'istruzione case
[4], come nell'esempio che segue.
Ruby
case inputLine
when "debug"
print "Debug"
when /p\s+(\w+)/
dumpVariable($1)
when "quit", "exit"
exit
else
print "Command: #{inputLine}"
end
Confronto con if-else
Lo switch-case
è una struttura di controllo che risulta, per molti versi, simile al costrutto if-else
. Questo può condurre al comune errore di considerarli ridondanti, mentre in realtà vi sono importanti differenze.
Ogni linguaggio ha le proprie caratteristiche, e questo si riflette anche sull'implementazione dei vari costrutti. Ciò che è vero per un linguaggio, può non essere corretto per un altro.
Differenze principali fra switch-case e if-else
Si può vedere un confronto sulle caratteristiche principali dei due costrutti:
- Nel costrutto
if-else
, il programmatore scrive esplicitamente un'espressione logica, che ne specifica la condizione. Nel costrutto switch-case, non viene scritta nessuna condizione: implicitamente, le condizioni che vengono verificate sono date dal confronto che viene fatto per verificare l'uguaglianza tra l'espressione indicata e ciascuna delle varie costanti corrispondenti ai casi.
- Come conseguenza della differenza precedente, il costrutto
if-else
(che ha una sola condizione) può scegliere solo tra due azioni diverse, corrispondenti alla condizione vera e falsa rispettivamente. Il costrutto switch-case
(che ha tante condizioni quanti gli casi) può scegliere tra azioni diverse, una per ogni caso ed eventualmente una di default.
- In molti linguaggi dove questo costrutto è implementato nel modo "classico" (con la sintassi C-like), è necessario terminare ogni case con un
break
. Non farlo, può significare eseguire codice non voluto.
- In presenza di molte condizioni da verificare, usare il costrutto
switch-case
può portare a un leggero guadagno di performance, a causa di possibili ottimizzazioni del compilatore.[5][6][7] Questo può non essere sempre vero, soprattutto in linguaggi di scripting.[8] In tutti i casi, gli aumenti di prestazioni il più delle volte non sono determinanti.
- In molte implementazioni, il costrutto
switch-case
richiede valori costanti. Nelle istruzioni if-else
, questo limite non esiste. Questo non è vero in molti linguaggi di scripting interpretati, a causa della tipizzazione dinamica che rende possibile utilizzare anche altri elementi. L'esempio soprastante in Ruby è un esempio.
Note
Collegamenti esterni