Quick Flow
switch는 하나의 정수·문자·enum 값으로 분기할 때 씁니다. 각 case는 자동으로 멈추지 않으므로 기본적으로 break를 두고, 범위 조건은 if/else로 처리합니다.
switch (command) {
case CMD_START:
start_engine();
break;
case CMD_STOP:
stop_engine();
break;
case CMD_HELP:
case CMD_VERSION:
print_usage(); /* 같은 동작은 label을 연속으로 둔다. */
break;
default:
fprintf(stderr, "unknown command\n");
break;
}case를 다음 case까지 그대로 통과시키는 일은 예외로 두고 의도를 표시합니다. 값의 범위 자체를 비교해야 하면 if/else가 더 직접적입니다.
분기 흐름
switch (expr)는 하나의 정수/문자/enum 값에 대해 여러 case를 나누는 분기문입니다. 값 하나를 기준으로 갈라지는 흐름일 때 적합하고, 범위 비교가 많아지면 if/else 쪽이 더 자연스럽습니다.
각 case 값은 정수 상수 표현식이어야 하고, 한 switch 안에서 같은 값이 두 번 나오면 안 됩니다. enum을 쓴다고 외부 정수 입력이 자동으로 enum 값으로 제한되지는 않으므로 default에서 처리 정책을 정합니다.
switch (score) {
case 0:
puts("zero");
break;
default:
puts("other");
break;
}흐름 제어
switch (menu) {
case 1:
printf("save\n");
case 2:
printf("quit\n");
break;
}위 코드는 menu == 1이어도 quit까지 실행됩니다. C의 switch는 case 내부에서 자동으로 멈추지 않습니다.
그래서 기본 태도는 이겁니다.
- 대부분 case 끝에는
break - 의도적으로 흘려보낼 때만 명시
switch (grade) {
case 'A':
case 'B':
printf("pass\n");
break;
case 'C':
printf("retry\n");
break;
}이 패턴은 괜찮습니다. 여러 case가 같은 동작을 공유하니까 읽는 사람도 자연스럽게 이해할 수 있습니다.
조금 더 위험한 형태는 "중간 로직 실행 후 다음 case로 일부러 흘리는" 경우입니다.
switch (level) {
case 3:
enable_logging();
/* fallthrough */
case 2:
enable_debug();
break;
}이 경우에는 주석이나 속성으로 의도를 분명히 남기는 편이 맞습니다.
C23 모드와 컴파일러가 지원하는 경우 [[fallthrough]];를 사용할 수 있습니다. 지원 범위가 불명확한 코드라면 동작을 바로 설명하는 주석과 함께, 가능한 한 case 묶음 형태로 다시 표현하는 편이 이식성이 좋습니다.
반대로 범위 분기에는 여전히 switch보다 if/else가 낫습니다.
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
}switch (score)로 90~100을 일일이 나누는 방식보다 읽기 쉽고, 의도도 더 분명합니다.
case 구성
예상 가능한 case를 다 썼다고 느껴도, 외부 입력이나 잘못된 상태가 들어오면 빠지는 값이 생길 수 있습니다.
- enum이더라도 외부 정수 입력은 범위 밖 값일 수 있다
- default가 없으면 조용히 아무 일도 안 하고 지나갈 수 있다
- 같은 동작을 공유하는 case 묶음은 자연스럽지만, 중간 로직 뒤 fallthrough는 의도 표시가 없으면 거의 실수처럼 읽힙니다.
case 안에서 지역 변수를 선언하고 초기화를 넘나드는 코드는 쉽게 꼬입니다. case별 상태가 필요하면 중괄호 블록으로 scope를 나눕니다.
case CMD_START: {
int result = start_engine();
report_result(result);
break;
}빠른 점검
- 값 기반 분기면
switch - 범위 분기면
if/else - 기본은
break - fallthrough는 의도 표시
- 예외값 대비
default
주의할 점
switch 안에서 변수를 선언하고 case를 넘나들면 초기화 건너뜀 문제로 바로 복잡해집니다. case별로 지역 상태가 필요하면 중괄호 블록으로 감싸서 scope를 분리하는 편이 안전합니다.
참고 링크
2 sources