C ++ switch 문에서 두 가지 경우가 모두 세 번째 경우로 넘어 가고 싶은 상황이 있습니다. 특히 두 번째 경우는 세 번째 경우로 넘어 가고 첫 번째 경우도 두 번째 경우 를 통과 하지 않고 세 번째 경우로 넘어갑니다 .
나는 멍청한 생각을 가지고 시도해 보았고 효과가있었습니다! 나는 두 번째의 경우 포장 if (0) {
… }
. 다음과 같이 보입니다.
#ifdef __cplusplus
# include <cstdio>
#else
# include <stdio.h>
#endif
int main(void) {
for (int i = 0; i < 3; i++) {
printf("%d: ", i);
switch (i) {
case 0:
putchar('a');
// @fallthrough@
if (0) { // fall past all of case 1 (!)
case 1:
putchar('b');
// @fallthrough@
}
case 2:
putchar('c');
break;
}
putchar('\n');
}
return 0;
}
실행하면 원하는 출력을 얻습니다.
0: ac
1: bc
2: c
나는 C와 C ++ (둘 다 clang과 함께)에서 시도해 보았고 같은 일을했습니다.
내 질문은 : 이것이 유효한 C / C ++입니까? 그것이하는 일을해야합니까?
답변
예, 이것은 허용되며 원하는 것을 수행합니다. A에 대한 switch
문은 C ++ 표준은 말합니다 :
대 / 소문자 및 기본 레이블 자체는 제어 흐름을 변경하지 않으며 이러한 레이블에서 방해받지 않고 계속됩니다. 스위치에서 나가려면 break를 참조하십시오.
[참고 1 : 일반적으로 스위치의 주제 인 하위 문은 복합이고 case 및 기본 레이블은 (복합) 하위 문에 포함 된 최상위 문에 표시되지만 필수는 아닙니다. 선언문은 switch 문의 하위 문에 나타날 수 있습니다. — 끝 참고]
따라서 if
명령문이 평가 될 때 if
중간 케이스 레이블에 관계없이 명령문 의 규칙에 따라 제어 흐름이 진행됩니다 .
답변
네, 작동합니다. C의 switch 문에 대한 case 레이블은 goto 레이블과 거의 똑같습니다 (중첩 된 switch 문에서 작동하는 방법에 대한 몇 가지주의 사항이 있음). 특히, 그들은 “사례 내부”라고 생각하는 문장에 대한 블록을 스스로 정의하지 않으며, goto에서 할 수있는 것처럼 블록의 중간으로 점프하는 데 사용할 수 있습니다. 블록 중간으로 점프 할 때 변수 초기화 등의 점프와 관련하여 goto와 동일한주의 사항이 적용됩니다.
그렇게 말하면 실제로 다음과 같이 goto 문으로 작성하는 것이 더 분명합니다.
switch (i) {
case 0:
putchar('a');
goto case2;
case 1:
putchar('b');
// @fallthrough@
case2:
case 2:
putchar('c');
break;
}
답변
다른 답변에서 언급했듯이 이것은 표준에서 기술적으로 허용되지만 향후 코드 독자에게는 매우 혼란스럽고 명확하지 않습니다.
이것이 switch ... case
문이 많은 인라인 코드가 아닌 함수 호출로 작성되어야하는 이유 입니다.
switch(i) {
case 0:
do_zero_case(); do_general_stuff(); break;
case 1:
do_one_case(); do_general_stuff(); break;
case 2:
do_general_stuff(); break;
default:
do_default_not_zero_not_one_not_general_stuff(); break;
}