switch statement
Transfers control to one of the several statements, depending on the value of a condition.
Syntax
attr(optional) switch ( condition ) statement | (until C++17) | |
attr(optional) switch ( init-statement(optional) condition ) statement | (since C++17) |
attr(C++11) | - | any number of attributes |
condition | - | any expression of integral or enumeration type, or of a class type contextually implicitly convertible to an integral or enumeration type, or a declaration of a single non-array variable of such type with a brace-or-equals initializer. |
init-statement(C++17) | - | either
; , which is why it is often described informally as an expression or a declaration followed by a semicolon. |
statement | - | any statement (typically a compound statement). case: and default: labels are permitted in statement and break; statement has special meaning. |
attr(optional) case constant_expression : statement | (1) | |
attr(optional) default : statement | (2) |
constant_expression | - | a constant expression of the same type as the type of condition after conversions and integral promotions |
Explanation
The body of a switch statement may have an arbitrary number of case:
labels, as long as the values of all constant_expressions are unique (after conversions/promotions). At most one default:
label may be present (although nested switch statements may use their own default:
labels or have case:
labels whose constants are identical to the ones used in the enclosing switch).
If condition evaluates to the value that is equal to the value of one of constant_expressions, then control is transferred to the statement that is labeled with that constant_expression.
If condition evaluates to the value that doesn't match any of the case:
labels, and the default:
label is present, control is transferred to the statement labeled with the default:
label.
The break statement, when encountered in statement exits the switch statement:
switch(1) {
case 1 : cout << '1'; // prints "1",
case 2 : cout << '2'; // then prints "2"
}
switch(1) {
case 1 : cout << '1'; // prints "1"
break; // and exits the switch
case 2 : cout << '2';
break;
}
Compilers may issue warnings on fallthrough (reaching the next case label without a break) unless the attribute If init-statement is used, the switch statement is equivalent to.
Except that names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope, which is also the scope of statement. | (since C++17) |
Because transfer of control is not permitted to enter the scope of a variable, if a declaration statement is encountered inside the statement, it has to be scoped in its own compound statement:
switch(1) {
case 1: int x = 0; // initialization
std::cout << x << '\n';
break;
default: // compilation error: jump to default: would enter the scope of 'x'
// without initializing it
std::cout << "default\n";
break;
}
switch(1) {
case 1: { int x = 0;
std::cout << x << '\n';
break;
} // scope of 'x' ends here
default: std::cout << "default\n"; // no error
break;
}
Keywords
Example
The following code shows several usage cases of the switch statement.
#include <iostream>
int main()
{
int i = 2;
switch (i) {
case 1: std::cout << "1";
case 2: std::cout << "2"; //execution starts at this case label
case 3: std::cout << "3";
case 4:
case 5: std::cout << "45";
break; //execution of subsequent statements is terminated
case 6: std::cout << "6";
}
std::cout << '\n';
switch (i) {
case 4: std::cout << "a";
default: std::cout << "d"; //there are no applicable constant_expressions
//therefore default is executed
}
std::cout << '\n';
switch (i) {
case 4: std::cout << "a"; //nothing is executed
}
// when enumerations are used in a switch statement, many compilers
// issue warnings if one of the enumerators is not handled
enum color {RED, GREEN, BLUE};
switch(RED) {
case RED: std::cout << "red\n"; break;
case GREEN: std::cout << "green\n"; break;
case BLUE: std::cout << "blue\n"; break;
}
// the C++17 init-statement syntax can be helpful when there is
// no implicit conversion to integral or enumeration type
switch (Device dev = get_device(); dev.state())
{
case SLEEP: /*...*/ break;
case READY: /*...*/ break;
case BAD: /*...*/ break;
}
// pathological examples
// the statement doesn't have to be a compound statement
switch(0)
std::cout << "this does nothing\n";
// labels don't require a compound statement either
switch(int n = 1)
case 0:
case 1: std::cout << n << '\n';
// Duff's Device: http://en.wikipedia.org/wiki/Duff's_device
}
Output:
2345 d red 1
See also
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/language/switch