Switch (programmazione)

Da Wikipedia, l'enciclopedia libera.

In programmazione lo switch, chiamato a volte anche switch-case, è una struttura di controllo che permette la verifica del valore di una 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 una 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[modifica | modifica wikitesto]

Una 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 false.

SWITCH variabile
     CASE '1': codice_1
     CASE '2': codice_2
     DEFAULT: raggiunto_se_condizioni_precedenti_non_vere
END

Esempi classici[modifica | modifica wikitesto]

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++[modifica | modifica wikitesto]

switch(numero)
{
    case 1:
        cout<<"1"<<endl;
        break;
        //Se questo break non ci fosse, verrebbero eseguiti anche i codici di "case 2", "case 3" e l'eventuale "default"

    case 2:
        cout<<"2"<<endl;
        break;

    case 3:
        cout<<"3"<<endl;
        break;

    default: //opzionale
        cout<<"Altro numero."<<endl;
}

PHP[modifica | modifica wikitesto]

$numero = rand(1,3);
switch ($numero)
{
    case 1:
        echo "è uscito 1";
        break;

    case 2:
        echo "è uscito 2";
        break;

    case 3:
        echo "è uscito 3";
        break;
}

Implementazione in altri linguaggi[modifica | modifica wikitesto]

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[modifica | modifica wikitesto]

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[modifica | modifica wikitesto]

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 ed if-else.[modifica | modifica wikitesto]

Si può vedere un confronto sulle caratteristiche principali dei due costrutti:

  1. Nel costrutto if-else, il programmatore scrive esplicitamente una 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.
  2. 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 N casi) può scegliere tra N +1 azioni diverse, una per ogni caso ed eventualmente una di default.
  3. 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.
  4. In presenza di molte condizioni da verificare, usare il costrutto switch-case può portare ad 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.
  5. 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[modifica | modifica wikitesto]

  1. ^ Why can't I have a variable in switch-case statement?, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  2. ^ Using variable for switch case statement, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  3. ^ perlsyn - perldoc.perl.org, su perldoc.perl.org. URL consultato il 09 ottobre 2015.
  4. ^ How can I write a switch statement in Ruby?, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  5. ^ Is 'switch' faster than 'if'?, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  6. ^ Is "else if" faster than "switch() case"?, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  7. ^ Why switch is faster than if, su stackoverflow.com. URL consultato il 09 ottobre 2015.
  8. ^ Ruby Performance : Case vs. If-elsif - Midwire, su midwire.github.io. URL consultato il 09 ottobre 2015.

Collegamenti esterni[modifica | modifica wikitesto]