switch ~ case

if(조건식) { 내용 } else if(조건식) { 내용 } else if(조건식) { 내용 }...을 반복하는 코드는 가독성이 떨어집니다. 이를 해결하기 위해 switch ~ case문이 존재합니다.

#include <stdio.h>
int main() {
      int a;
      scanf("%d", &a);
      switch(a) {
      case 0:
            printf("Zero\n");
            break;
      case 1:
            printf("One\n");
            break;
      case 2:
            printf("Two\n");
            break;
      case 3:
            printf("Three\n");
            break;
      default:
            printf("Other\n");
            break;
      }
      return 0;
}

0

Zero


1

One


2

Two


3

Three


100

Other

switch ~ case문에서는 switch에 들어가는 수에 해당하는 라벨로 점프합니다. 해당하는 라벨이 없다면 default 라벨로 점프합니다. switch ~ case문은 if문과 달리 점프할 뿐이므로 아래의 코드들을 실행하고 싶지 않다면 break를 통해 switch ~ case문을 멈추어야 합니다.

#include <stdio.h>
int main() {
      int a;
      scanf("%d", &a);
      switch(a) {
      case 0:
            printf("Zero\n");
      case 1:
            printf("One\n");
      case 2:
            printf("Two\n");
      case 3:
            printf("Three\n");
      default:
            printf("Other\n");
      }
      return 0;
}

1

One
Two
Three
Other

switch에 들어가는 값은 항상 정수여야 합니다. 또, 레이블의 수는 반드시 정수형 컴파일 타임 상수여야 합니다. const는 런타임 상수입니다! 정수만 가능한 것은 아까 잠시 보여주었던 레이블의 배열과 관련이 있습니다. 첫 번째 switch ~ case문을 gotoif로 바꾸면(컴파일 결과로 나온 어셈블리어를 있는 그대로 C 언어로 옮기면)

#include <stdio.h>
int main() {
      int a;
      scanf("%d", &a);
      if(a > 3)
            goto other;
      if(a == 0)
            goto l0;
      if(a == 1)
            goto l1;
      if(a == 2)
            goto l2;
      if(a == 3)
            goto l3;
l0:
      printf("Zero\n");
      goto switch_end;
l1:
      printf("One\n");
      goto switch_end;
l2:
      printf("Two\n");
      goto switch_end;
l3:
      printf("Three\n");
      goto switch_end;
other:
      printf("Other\n");
      goto switch_end;
switch_end:
      return 0;
}

이런 코드가 나옵니다. 조금 더 똑똑한 컴파일러는

#include <stdio.h>
int main() {
      int a;
      scanf("%d", &a);
      void* label[ 4 ] = { &&l0, &&l1, &&l2, &&l3 };
      if(a > 3)
            goto other;
      goto *label[ a ];
l0:
      printf("Zero\n");
      goto switch_end;
l1:
      printf("One\n");
      goto switch_end;
l2:
      printf("Two\n");
      goto switch_end;
l3:
      printf("Three\n");
      goto switch_end;
other:
      printf("Other\n");
      goto switch_end;
switch_end:
      return 0;
}

이렇게 바꿔주는데, 대부분의 경우 배열의 n번째 원소에 접근하는 것은 무척 싼 작업이나 if 문을 사용하는 것은 비싼 작업이기 때문에 후자가 성능을 높이는 데 유리합니다. 이러한 작업을 위해 C 언어에서는 switch ~ case 문에서 정수만 사용할 수 있게 합니다. 물론 언어나 컴파일러에 따라서는 그렇지 않은 경우도 있습니다.