답변:
많은 답변 이 진술 을 요구하는 이유 로서 넘어 질 수있는 능력에 초점을 맞추는 것 같습니다 break
.
나는 C가 설계되었을 때 이러한 구조가 어떻게 사용되는지에 대한 경험이 거의 없기 때문에 단순히 실수라고 생각합니다.
Peter Van der Linden은 자신의 저서 "Expert C Programming"에서 다음과 같이 설명합니다.
Sun C 컴파일러 소스를 분석하여 기본 폴 스루 사용 빈도를 확인했습니다. Sun ANSI C 컴파일러 프론트 엔드에는 244 개의 switch 문이 있으며 각 문에는 평균 7 개의 사례가 있습니다. 이 모든 경우의 3 %만으로 넘어집니다.
다시 말해서, 정상적인 스위치 동작은 97 %의 시간에 잘못 되었습니다. 이는 컴파일러에만있는 것이 아닙니다. 반대로이 분석에서 사용 된 추락은 종종 다른 소프트웨어보다 컴파일러에서 더 자주 발생하는 상황 (예 : 하나 또는 두 개의 피연산자를 가질 수있는 연산자를 컴파일 할 때)이었습니다. :
switch (operator->num_of_operands) { case 2: process_operand( operator->operand_2); /* FALLTHRU */ case 1: process_operand( operator->operand_1); break; }
케이스 폴 스루는 결함으로 널리 인식되어 있으며 위에서 보인 것처럼 보풀을 알려주는 특별한 주석 규칙도 있습니다. "이는 실제로 폴 스루가 필요한 경우의 3 % 중 하나입니다."
C #이 각 사례 블록의 끝에 명시 적 점프 명령문을 요구하는 것이 좋습니다 (단일 문장 블록이있는 한 여러 사례 레이블을 쌓을 수는 있음). C #에서는 한 사례가 다른 사례로 넘어갈 수 있습니다 goto
.를 사용하여 다음 사례로 넘어 가서 명시 적으로 넘어야합니다 .
Java가 C 의미를 벗어날 기회를 얻지 못한 것은 너무 나쁩니다.
여러 가지면에서 c는 표준 어셈블리 관용구에 대한 깔끔한 인터페이스입니다. 점프 테이블 구동 흐름 제어를 작성할 때, 프로그래머는 "제어 구조"를 통해 넘어 지거나 뛰어 내릴 수 있습니다.
그래서 c도 같은 일을합니다.
NULL
NUL
문자열은 최악의 생각입니다.
DO
루프 의 디자인보다 나쁘지 않습니다 .
더프의 장치를 구현하려면 분명히 :
dsend(to, from, count)
char *to, *from;
int count;
{
int n = (count + 7) / 8;
switch (count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
}
사례가 암시 적으로 중단되도록 설계된 경우에는 실패 할 수 없었습니다.
case 0:
case 1:
case 2:
// all do the same thing.
break;
case 3:
case 4:
// do something different.
break;
default:
// something else entirely.
모든 경우에 스위치가 암시 적으로 발생하도록 설계된 경우 스위치를 선택할 수 없습니다. 스위치 케이스 구조는보다 유연하게 설계되었습니다.
switch 문에있는 case 문은 단순히 레이블입니다.
값을 켤 때 switch 문은 본질적으로 goto를 수행합니다. 일치하는 값으로 레이블을.
즉, 다음 레이블 아래의 코드를 통과하지 않으려면 나누기가 필요합니다.
이것이 이런 식으로 구현 된 이유에 대해서는 switch 문의 폴-스루 특성이 일부 시나리오에서 유용 할 수 있습니다. 예를 들면 다음과 같습니다.
case optionA:
// optionA needs to do its own thing, and also B's thing.
// Fall-through to optionB afterwards.
// Its behaviour is a superset of B's.
case optionB:
// optionB needs to do its own thing
// Its behaviour is a subset of A's.
break;
case optionC:
// optionC is quite independent so it does its own thing.
break;
break
필요한 곳을 잊어 버렸습니다 . 2) 사례 명세서의 순서가 변경되면 오류가 발생하여 잘못된 사례가 실행될 수 있습니다. 따라서 C #의 처리가 훨씬 우수하다는 것을 알았습니다 ( goto case
빈 사례 레이블을 제외하고는 추락에 대해 명시 적임).
break
C #에서도 잊을 수 있는 방법이 있습니다. 가장 간단한 방법 case
은 아무것도 하고 싶지 않지만 추가하는 것을 잊었을 때입니다 break
(아마 설명 주석으로 묶여 있거나 다른 작업) : 실행은 case
아래로 넘어갑니다 . 2) 격려 goto case
는 구조화되지 않은 "스파게티"코딩을 장려합니다 case A: ... goto case B; case B: ... ; goto case A;
. 특히 케이스가 파일에서 분리되어 조합되어 이해하기 어려운 경우 우발적 인주기 ( ) 로 끝날 수 있습니다 . C ++에서 폴 스루는 현지화되어 있습니다.
다음과 같은 것을 허용하려면 :
switch(foo) {
case 1:
/* stuff for case 1 only */
if (0) {
case 2:
/* stuff for case 2 only */
}
/* stuff for cases 1 and 2 */
case 3:
/* stuff for cases 1, 2, and 3 */
}
case
키워드를 goto
레이블 로 생각하면 더 자연스럽게 나타납니다.
if(0)
제 1 케이스의 단부에 악 대물 코드를 당황하게하는 경우에만 사용되어야한다.
벡터에 값을 구조체에 할당하는 경우가 발생했습니다. 데이터 벡터가 구조체의 데이터 멤버 수보다 짧으면 나머지 멤버는 그대로 유지되도록해야했습니다. 그들의 기본값. 이 경우 생략 break
이 매우 유용했습니다.
switch (nShorts)
{
case 4: frame.leadV1 = shortArray[3];
case 3: frame.leadIII = shortArray[2];
case 2: frame.leadII = shortArray[1];
case 1: frame.leadI = shortArray[0]; break;
default: TS_ASSERT(false);
}
여기에 많은 사람들이 지정한 것처럼 단일 코드 블록이 여러 경우에 작동하도록 허용합니다. 이것은 해야 예에서 지정한 "사례 당 코드 블록"보다 switch 문에서 더 일반적으로 발생 합니다.
폴 스루없이 사례 당 코드 블록이있는 경우 if-elseif-else 블록을 사용하는 것이 더 적절 해 보일 수 있습니다.