Condividi tramite


switch istruzione (C++)

Consente la selezione tra più sezioni di codice, in base al valore di un'espressione integrale.

Sintassi

selection-statement:
switch(init-statementoptC++17condition)statement

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqopt decl-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.

Vedi anche

Istruzioni di selezione
Parole chiave