switch 문이 휴식을 취하도록 설계된 이유는 무엇입니까?
간단한 switch 문이 주어지면
switch (int)
{
case 1 :
{
printf("1\n");
break;
}
case 2 :
{
printf("2\n");
}
case 3 :
{
printf("3\n");
}
}
사례 2에 break 문이 없으면 사례 3의 코드 내에서 실행이 계속됨을 의미합니다. 이것은 우연이 아닙니다. 그런 식으로 설계되었습니다. 이 결정이 내려진 이유는 무엇입니까? 이것이 블록에 대한 자동 중단 의미를 갖는 것과 비교하여 어떤 이점이 있습니까? 근거는 무엇입니까?
많은 답변 이 진술 을 요구하는 이유 로서 넘어 질 수있는 능력에 초점을 맞추는 것 같습니다 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
.를 사용하여 다음 사례로 넘어 가서 명시 적으로 넘어야합니다 .
자바가 C 의미론에서 벗어날 기회를 얻지 못한 것은 너무 나쁘다.
많은면에서 c는 표준 어셈블리 관용구에 대한 깔끔한 인터페이스입니다. 점프 테이블 구동 흐름 제어를 작성할 때, 프로그래머는 "제어 구조"를 통해 넘어 지거나 뛰어 내릴 수 있습니다.
그래서 c도 같은 일을합니다.
더프의 장치를 구현하려면 분명히 :
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);
}
}
If cases were designed to break implicitly then you couldn't have fallthrough.
case 0:
case 1:
case 2:
// all do the same thing.
break;
case 3:
case 4:
// do something different.
break;
default:
// something else entirely.
If the switch was designed to break out implicitly after every case you wouldn't have a choice about it. The switch-case structure was designed the way it is to be more flexible.
The case statements in a switch statements are simply labels.
When you switch on a value, the switch statement essentially does a goto to the label with the matching value.
This means that the break is necessary to avoid passing through to the code under the next label.
As for the reason why it was implemented this way - the fall-through nature of a switch statement can be useful in some scenarios. For example:
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;
To allow things like:
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 */
}
Think of the case
keyword as a goto
label and it comes a lot more naturally.
It eliminates code duplication when several cases need to execute the same code (or the same code in sequence).
Since on the assembly language level it doesn't care whether you break between each one or not there is zero overhead for fall through cases anyways, so why not allow them since they offer significant advantages in certain cases.
I happened to run in to a case of assigning values in vectors to structs: it had to be done in such a manner that if the data vector was shorter than the number of data members in the struct, the rest of the members would remain in their default value. In that case omitting break
was quite useful.
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);
}
As many here have specified, it's to allow a single block of code to work for multiple cases. This should be a more common occurrence for your switch statements than the "block of code per case" you specify in your example.
If you have a block of code per case without fall-through, perhaps you should consider using an if-elseif-else block, as that would seem more appropriate.
참고URL : https://stackoverflow.com/questions/252489/why-was-the-switch-statement-designed-to-need-a-break
'IT story' 카테고리의 다른 글
datetime.parse 및 특정 형식으로 작동하게 만들기 (0) | 2020.06.30 |
---|---|
스칼라에서 이해력과 루프를 최적화하는 방법은 무엇입니까? (0) | 2020.06.30 |
가져온 모듈을 나열하는 방법? (0) | 2020.06.30 |
ConcurrentHashMap 및 동기화 된 HashMap (0) | 2020.06.30 |
HAXM 설치 중 오류, VT-X가 작동하지 않습니다 (0) | 2020.06.30 |