switch
istruzione (C++)
Consente la selezione tra più sezioni di codice, in base al valore di un'espressione integrale.
Sintassi
selection-statement
:
switch
(
init-statement
optC++17condition
)
statement
init-statement
:
expression-statement
simple-declaration
condition
:
expression
attribute-specifier-seq
optdecl-specifier-seq
declarator
brace-or-equal-initializer
labeled-statement
:
case
constant-expression
:
statement
default
:
statement
Osservazioni:
Un'istruzione switch
fa sì che il controllo si trasferisca a uno labeled-statement
nel corpo dell'istruzione, a seconda del valore di condition
.
Deve condition
avere un tipo integrale o essere un tipo di classe con una conversione non ambigua nel tipo integrale. La promozione integrale avviene come descritto in Conversioni standard.
Il corpo dell'istruzione switch
è costituito da una serie di case
etichette e da un'etichetta facoltativa default
. Un labeled-statement
è una di queste etichette e le istruzioni che seguono. Le istruzioni etichettate non sono requisiti sintattici, ma l'istruzione switch
non ha significato senza di esse. Nessun valore constant-expression
nelle case
istruzioni può restituire lo stesso valore. L'etichetta default
può essere visualizzata una sola volta. L'istruzione default
viene spesso posizionata alla fine, ma può essere visualizzata ovunque nel corpo dell'istruzione switch
. Un'etichetta case
o default
può essere visualizzata solo all'interno di un'istruzione switch
.
In constant-expression
ogni case
etichetta viene convertito in un valore costante che corrisponde allo stesso tipo di condition
. Quindi, viene confrontato con condition
per uguaglianza. Il controllo passa alla prima istruzione dopo il case
constant-expression
valore corrispondente al valore di condition
. Il comportamento risultante è illustrato nella tabella seguente.
switch
comportamento dell'istruzione
Condizione | Azione |
---|---|
Il valore convertito corrisponde a quello dell'espressione di controllo promossa. | Il controllo viene trasferito all'istruzione che segue tale etichetta. |
Nessuna delle costanti corrisponde alle costanti nelle case etichette. È presente un'etichetta default . |
Il controllo viene trasferito all'etichetta default . |
Nessuna delle costanti corrisponde alle costanti nelle case etichette. Nessuna default etichetta è presente. |
Il controllo viene trasferito all'istruzione dopo l'istruzione switch . |
Se viene trovata un'espressione corrispondente, l'esecuzione può continuare con etichette o default
versioni successivecase
. L'istruzione break
viene usata per arrestare l'esecuzione e trasferire il controllo all'istruzione dopo l'istruzione switch
. Senza un'istruzione break
, viene eseguita ogni istruzione dall'etichetta corrispondente case
alla fine di switch
, incluso , default
. Ad esempio:
// switch_statement1.cpp
#include <stdio.h>
int main() {
const char *buffer = "Any character stream";
int uppercase_A, lowercase_a, other;
char c;
uppercase_A = lowercase_a = other = 0;
while ( c = *buffer++ ) // Walks buffer until NULL
{
switch ( c )
{
case 'A':
uppercase_A++;
break;
case 'a':
lowercase_a++;
break;
default:
other++;
}
}
printf_s( "\nUppercase A: %d\nLowercase a: %d\nTotal: %d\n",
uppercase_A, lowercase_a, (uppercase_A + lowercase_a + other) );
}
Nell'esempio precedente uppercase_A
viene incrementato se c
è una 'A'
maiuscola. L'istruzione break
dopo uppercase_A++
l'interruzione dell'esecuzione del corpo dell'istruzione e del switch
controllo passa al while
ciclo. Senza l'istruzione , l'esecuzione break
passerebbe all'istruzione etichettata successiva, in modo che lowercase_a
e other
verrebbe incrementata. Uno scopo simile viene gestito dall'istruzione break
per case 'a'
. Se c
è un valore minuscolo 'a'
, lowercase_a
viene incrementato e l'istruzione termina il corpo dell'istruzione break
switch
. Se c
non è o 'a'
'A'
, viene eseguita l'istruzione default
.
Visual Studio 2017 e versioni successive (disponibili in /std:c++17
modalità e versioni successive): l'attributo [[fallthrough]]
è specificato nello standard C++17. È possibile usarlo in un'istruzione switch
. Si tratta di un suggerimento per il compilatore o per chiunque legge il codice, che il comportamento di fall-through sia intenzionale. Il compilatore Microsoft C++ attualmente non avvisa sul comportamento di fallthrough, quindi questo attributo non ha alcun effetto sul comportamento del compilatore. Nell'esempio l'attributo viene applicato a un'istruzione vuota all'interno dell'istruzione etichettata senza nome. In altre parole, il punto e virgola è necessario.
int main()
{
int n = 5;
switch (n)
{
case 1:
a();
break;
case 2:
b();
d();
[[fallthrough]]; // I meant to do this!
case 3:
c();
break;
default:
d();
break;
}
return 0;
}
Visual Studio 2017 versione 15.3 e successive (disponibile in /std:c++17
modalità e versioni successive): un'istruzione switch
può avere una init-statement
clausola che termina con un punto e virgola. Introduce e inizializza una variabile il cui ambito è limitato al blocco dell'istruzione switch
:
switch (Gadget gadget(args); auto s = gadget.get_status())
{
case status::good:
gadget.zip();
break;
case status::bad:
throw BadGadget();
};
Un blocco interno di un'istruzione switch
può contenere definizioni con inizializzatori purché siano raggiungibili, ovvero non ignorati da tutti i possibili percorsi di esecuzione. I nomi introdotti utilizzando queste dichiarazioni hanno ambito locale. Ad esempio:
// switch_statement2.cpp
// C2360 expected
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
switch( tolower( *argv[1] ) )
{
// Error. Unreachable declaration.
char szChEntered[] = "Character entered was: ";
case 'a' :
{
// Declaration of szChEntered OK. Local scope.
char szChEntered[] = "Character entered was: ";
cout << szChEntered << "a\n";
}
break;
case 'b' :
// Value of szChEntered undefined.
cout << szChEntered << "b\n";
break;
default:
// Value of szChEntered undefined.
cout << szChEntered << "neither a nor b\n";
break;
}
}
Un'istruzione switch
può essere annidata. In caso di annidamento, le case
etichette o default
vengono associate all'istruzione più switch
vicina che le racchiude.
Comportamento specifico di Microsoft
Microsoft C++ non limita il numero di case
valori in un'istruzione switch
. Tale numero è limitato solo dalla memoria disponibile.