switch 문(switch statement)
switch 문(switch statement)
정수 값에 따라 여러 분기 중 하나로 실행을 옮기고 싶을 때 쓰는 게 switch 문이에요. 정수 값에 따라 많은 분기 중 하나 혹은 여러 개를 실행할 때 사용해요.
출처: cppreference
본문
문법
attr-spec-seq(선택) switch ( expression ) statement |
| 항목 | 의미 | |
|---|---|---|
| attr-spec-seq | - | (C23부터) switch 문에 적용되는 선택적 속성 목록 |
| expression | - | 정수 타입의 임의의 표현식(char, 부호 있는 정수, 부호 없는 정수, 또는 열거) |
| statement | - | 임의의 문(보통 복합 문). statement 안에 case:와 default: 레이블이 허용되고, break; 문은 특별한 의미를 가져요. |
레이블:
case constant-expression : statement |
(1) (C23 이전) |
attr-spec-seq(선택) case constant-expression : statement(선택) |
(1) (C23부터) |
default : statement |
(2) (C23 이전) |
attr-spec-seq(선택) default : statement(선택) |
(2) (C23부터) |
| 항목 | 의미 | |
|---|---|---|
| constant-expression | - | 임의의 정수 상수 표현식 |
| attr-spec-seq | - | (C23부터) 레이블에 적용되는 선택적 속성 목록 |
설명(Explanation)
switch 문의 본문은 임의의 개수의 case: 레이블을 가질 수 있어요. 단, 모든 constant-expression의 값(expression의 승격된 타입으로 변환한 뒤)이 유일해야 해요. default: 레이블은 기껏해야 하나 있을 수 있어요(단, 중첩된 switch 문은 자신만의 default: 레이블이나, 감싸는 switch에서 쓰인 것과 같은 상수를 가진 case: 레이블을 쓸 수 있어요).
expression이 평가되어 그 값이 constant-expression 중 하나의 값과(expression의 승격된 타입으로 변환한 뒤) 같으면, 제어는 그 constant-expression이 레이블로 붙은 문으로 이동해요.
expression이 평가된 값이 어떤 case: 레이블과도 일치하지 않고 default: 레이블이 있으면, 제어는 default: 레이블이 붙은 문으로 이동해요.
expression이 평가된 값이 어떤 case: 레이블과도 일치하지 않고 default: 레이블도 없으면, switch 본문 중 어떤 것도 실행되지 않아요.
break 문은 statement 안 어디서 만나든 switch 문을 빠져나가요:
switch(1) {
case 1 : puts("1"); // prints "1",
case 2 : puts("2"); // then prints "2" ("fall-through")
}
switch(1) {
case 1 : puts("1"); // prints "1"
break; // and exits the switch
case 2 : puts("2");
break;
}
다른 모든 선택·반복 문과 마찬가지로 switch 문은 블록 범위를 확립해요. expression에서 도입된 식별자는 문이 끝난 뒤 범위를 벗어나요.
VLA 또는 가변 수정(variably-modified) 타입의 다른 식별자가 자신의 범위 안에 case: 또는 default: 레이블을 가지면, 전체 switch 문이 그 범위 안에 있어야 해요(다시 말해 VLA는 전체 switch 이전이나 마지막 레이블 이후에 선언되어야 해요):
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
}
키워드(Keywords)
switch, case, default
예제(Example)
아래 코드는 switch 문의 분기와 낙하(fall-through)가 실제로 어떻게 흐르는지 보여줘요.
#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:
case 6: printf("case 5 or case 6, ");
default: printf("default.\n");
}
}
int main(void)
{
for(int i = 1; i < 9; ++i) func(i);
}
출력:
func(1): case 1, case 2, case 3.
func(2): case 2, case 3.
func(3): case 3.
func(4): case 4, case 5 or case 6, default.
func(5): case 5 or case 6, default.
func(6): case 5 or case 6, default.
func(7): default.
func(8): default.
case 1:과 case 2:에 break가 없어서 case 3:의 break까지 낙하로 계속 이어져요. case 5:는 본문이 없어 case 6:으로 바로 떨어지고, case 6:과 default: 사이에도 break가 없어 default까지 내려가요.