Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Instruction
Autorise la sélection parmi plusieurs sections de code, selon la valeur d'une expression intégrale.
Syntaxe
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
Notes
Une instruction switch
entraîne le transfert du contrôle à une labeled-statement
dans son corps d’instruction, en fonction de la valeur de condition
.
La condition
doit avoir un type intégral, ou être un type de classe qui a une conversion non ambiguë en type intégral. La promotion intégrale a lieu comme décrit dans Conversions standard.
Le corps de l’instruction switch
consiste en une série d’étiquettes case
et une étiquette optionnelle default
. labeled-statement
est une de ces étiquettes et les instructions qui suivent. Les instructions étiquetées ne sont pas des exigences syntaxiques mais sans elles, l’instruction switch
n’a pas de sens. Deux valeurs constant-expression
dans les instructions case
ne peuvent pas s’évaluer à la même valeur. L’étiquette default
ne peut apparaître qu’une seule fois. L’instruction default
est souvent placée à la fin, mais elle peut apparaître n’importe où dans le corps de l’instruction switch
. Une étiquette case
ou default
ne peut apparaître qu’à l’intérieur d’une instruction switch
.
La constant-expression
dans chaque étiquette de case
est convertie en une valeur de constante qui est du même type que condition
. Ensuite, elle est comparée à condition
pour l’égalité. Le contrôle passe à la première instruction après la valeur case
constant-expression
qui correspond à la valeur de condition
. Le comportement résultant est indiqué dans le tableau suivant.
Comportement de l’instruction switch
Condition | Action |
---|---|
La valeur convertie correspond à celle de l'expression de contrôle promue. | Le contrôle est transféré à l'instruction qui suit cette étiquette. |
Aucune des constantes ne correspond aux constantes des étiquettes case ; une étiquette default est présente. |
Le contrôle est transféré à l’étiquette default . |
Aucune des constantes ne correspond aux constantes des étiquettes case ; aucune étiquette default n’est présente. |
Le contrôle est transféré à l’instruction qui suit l’instruction switch . |
Si une expression correspondante est trouvée, l’exécution peut continuer avec des étiquettes case
ou default
qui suivent. L’instruction break
est utilisée pour arrêter l’exécution et transférer le contrôle à l’instruction qui se trouve après l’instruction switch
. En l’absence d’une instruction break
, chaque instruction, depuis l’étiquette case
correspondante jusqu’à la fin de l’instruction switch
, y compris default
, est exécutée. Par exemple :
// 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) );
}
Dans l'exemple ci-dessus, uppercase_A
est incrémenté si c
est un 'A'
majuscule. L’instruction break
après uppercase_A++
arrête l’exécution du corps de l’instruction switch
et le contrôle passe à la boucle while
. Sans l’instruction break
, l’exécution passerait à l’instruction étiquetée suivante afin que lowercase_a
et other
soient également incrémentés. Un objectif similaire est réalisé par l’instruction break
pour case 'a'
. Si c
est une minuscule 'a'
, lowercase_a
est incrémenté et l’instruction break
termine le corps de l’instruction switch
. Si c
n’est pas un 'a'
ou un 'A'
, l’instruction default
est exécutée.
Visual Studio 2017 et ultérieur (disponible en mode /std:c++17
et ultérieur) : l’attribut [[fallthrough]]
est spécifié dans le standard C++17. Vous pouvez l’utiliser dans une instruction switch
. C’est un indicateur pour le compilateur ou pour toute personne lisant le code, ce comportement de fourre-tout est intentionnel. Actuellement, le compilateur Microsoft C++ ne produit pas d’avertissement pour le comportement de fourre-tout : cet attribut n’a donc pas d’ effet sur le comportement du compilateur. Dans l’exemple, l’attribut est appliqué à une instruction vide dans l’instruction étiquetée non terminée. En d’autres termes, le point-virgule est nécessaire.
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 version 15.3 et ultérieure (disponible en mode /std:c++17
et ultérieur) : une instruction switch
peut avoir une clause init-statement
qui se termine par un point-virgule. Elle introduit et initialise une variable dont l’étendue est limitée au bloc de l’instruction switch
:
switch (Gadget gadget(args); auto s = gadget.get_status())
{
case status::good:
gadget.zip();
break;
case status::bad:
throw BadGadget();
}
Un bloc interne d’une instruction switch
peut contenir des définitions avec des initialiseurs dès lors qu’ils sont accessibles, c’est-à-dire non contournés par tous les chemins d’exécution possibles. Les noms présentés à l'aide de ces déclarations ont une portée locale. Par exemple :
// 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;
}
}
Une instruction switch
peut être imbriquée. Dans ce cas, les étiquettes case
ou default
s’associent à l’instruction switch
la plus proche autour d’elles.
Comportement spécifique à Microsoft
Microsoft C++ ne limite pas le nombre de valeurs case
dans une instruction switch
. Le nombre est limité uniquement par la mémoire disponible.