switch statement
Executes code according to the value of an integral argument.
Used where one or several out of many branches of code need to be executed according to an integral value.
Syntax
attr-spec-seq(optional) switch ( expression ) statement
|
|||||||||
attr-spec-seq | - | (C23)optional list of attributes, applied to the switch statement
|
expression | - | any expression of integer type (char, signed or unsigned integer, or enumeration) |
statement | - | any statement (typically a compound statement). case: and default: labels are permitted in statement, and break; statement has special meaning.
|
case constant-expression : statement
|
(1) | (until C23) | |||||||
attr-spec-seq(optional) case constant-expression : statement(optional)
|
(1) | (since C23) | |||||||
default : statement
|
(2) | (until C23) | |||||||
attr-spec-seq(optional) default : statement(optional)
|
(2) | (since C23) | |||||||
constant-expression | - | any integer constant expression |
attr-spec-seq | - | (C23)optional list of attributes, applied to the label |
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 conversion to the promoted type of expression). 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 expression evaluates to the value that is equal to the value of one of constant-expressions after conversion to the promoted type of expression, then control is transferred to the statement that is labeled with that constant-expression.
If expression evaluates to a 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.
If expression evaluates to a value that doesn't match any of the case:
labels, and the default:
label is not present, none of the switch body is executed.
The break statement, when encountered anywhere in statement, exits the switch statement:
As with all other selection and iteration statements, the switch statement establishes block scope: any identifier introduced in the expression goes out of scope after the statement. If a VLA or another identifier with variably-modified type has a switch (expr) { int i = 4; // not a VLA; OK to declare here f(i); // never called // int a[i]; // error: VLA cannot be declared here case 0: i = 17; default: int a[i]; // OK to declare VLA here printf("%d\n", i); // prints 17 if expr == 0, prints indeterminate value otherwise } |
(since C99) |
Keywords
Example
#include <stdio.h> void func(int x) { printf("func(%d): ", x); switch(x) { case 1: printf("case 1, "); case 2: printf("case 2, "); case 3: printf("case 3.\n"); break; case 4: printf("case 4, "); case 5: printf("case 5, "); default: printf("default.\n"); } } int main(void) { for(int i = 1; i < 9; ++i) func(i); }
Output:
func(1): case 1, case 2, case 3. func(2): case 2, case 3. func(3): case 3. func(4): case 4, case 5, default. func(5): case 5, default. func(6): default. func(7): default. func(8): default.
References
- C17 standard (ISO/IEC 9899:2018):
- 6.8.4.2 The switch statement (p: 108-109)
- C11 standard (ISO/IEC 9899:2011):
- 6.8.4.2 The switch statement (p: 149-150)
- C99 standard (ISO/IEC 9899:1999):
- 6.8.4.2 The switch statement (p: 134-135)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.6.4.2 The switch statement