Skip to content

21. switch 분기문


1. 키워드

  • switch 분기문
  • case
  • default


2. switch 분기문으로 다양한 조건 처리하기

  • switch 분기문은 조건이 많아도 손쉽게 처리할 수 있다.


001


  • switch 분기문은 항상 case와 함께 사용하는데 변수의 값이 case에 지정한 값과 일치하면 해당 코드를 실행하게 된다.
  • 단, case에는 조건식이나 변수를 지정할 수 없다.
  • 어떤 case에도 해당되지 않으면 default의 코드를 실행하는데, 이때 default는 생략할 수 있다.
  • switch 분기문은 형식이 균일하며 처리해야 할 조건이 많을 때 사용한다.


3. 사용자가 입력한 값에 따라 문자열 출력하기

  • switchcase를 간단하게 테스트 해보는 방법은 사용자가 입력한 값에 따라 문자열을 출력하는 것이다.


switch (변수)
{
case 숫자1:
    코드1
    break;
case 숫자2:
    코드2
    break;
default:
    코드3:
    break;
}


  • 다음 내용을 입력한다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    int num1;

    scanf("%d", &num1); // 값을 입력받음

    switch (num1) // num1의 값에 따라 분기
    {
    case 1: // 1일 때
        printf("1입니다.\n");
        break;
    case 2: // 2일 때
        printf("2입니다.\n");
        break;
    default: // 아무 case에도 해당되지 않을 때
        printf("default\n");
        break;
    }

    return 0;
}

// 1 (입력)
// 1입니다.


  • 1을 입력했으므로 "1입니다." 문자열이 출력된다.


  • switch()(괄호) 안에는 먼저 값을 판단할 변수를 지정한다.
  • 여기서는 scanf로 사용자의 입력을 받은 뒤 switchnum1 변수를 지정했다.
  • 그리고 case1일 때, 2일 때 그리고 default로 아무 case에도 해당하지 않을 때 실행할 코드를 지정했다.


switch (num1) // num1의 값에 따라 분기
{
case 1: // 1일 때
    printf("1입니다.\n");
    break;
case 2: // 2일 때
    printf("2입니다.\n");
    break;
default: // 아무 case에도 해당되지 않을 때
    printf("default\n");
    break;
}


  • case 다음에는 반드시 값(리터럴)이 와야 하며 변수나 조건식은 올 수 없다.
  • 그리고 case에 값을 지정했으면 :(콜론)을 붙여준 뒤 다음 줄부터 실행할 코드를 입력한다.
  • 또한, 코드의 마지막에는 break를 입력한다.


  • 이 코드를 switch 분기문 대신 if 조건문으로 표현하면 다음과 같은 모양이 된다.


if (num1 == 1) // 1일 때
    printf("1입니다.\n");
else if (num1 == 2) // 2일 때
    printf("2입니다.\n");
else // 1도 아니고 2도 아닐 때
    printf("default\n");


  • if 조건문은 첫 조건식 다음에 else if로 다른 조건식을 일일이 지정해 줘야 한다.
  • 즉, 조건식이 바뀌지 않고 값만 바뀔 때는 switch 분기문이 적합하며, 값과 조건식이 모두 바뀔 때는 else if가 적합하다.


4. case에서 break를 사용하지 않을 때의 동작 알아보기

  • 지금까지 각 case마다 break를 붙여주었는데, 앞의 소스 코드에서 break를 모두 삭제한다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    int num1;

    scanf("%d", &num1); // 값을 입력받음

    switch (num1) // num1의 값에 따라 분기
    {
    case 1: // 1일 때
        printf("1입니다.\n");
    case 2: // 2일 때
        printf("2입니다.\n");
    default: // 아무 case에도 해당되지 않을 때
        printf("default\n");
    }

    return 0;
}

// 1 (입력)
// 1입니다.
// 2입니다.
default


  • case 1:만 실행될 줄 알았는데 case 2:, default:가 모두 실행되었다.
  • 즉, case를 작성할 때는 마지막 부분에서 break로 중단해 줘야 해당 case만 실행된다.
  • 그러므로 casebreak로 중단하지 않으면 그다음에 있는 case, default가 계속 실행된다.
  • 이런 상황을 Fall Through라고 부른다.


5. case에서 break 생략 응용하기

  • case에서 break를 생략하는 상황은 버그 같지만 실제로는 많이 사용되는 방식이다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    int num1;

    scanf("%d", &num1); // 값을 입력받음

    switch (num1)
    {
    case 1: // 1 또는
    case 2: // 2일 때 코드 실행
        printf("1 또는 2입니다.\n");
        break;
    case 3: // 3 또는
    case 4: // 4일 때 코드 실행
        printf("3 또는 4입니다.\n");
        break;
    default:
        printf("default\n");
    }

    return 0;
}

// 1 (입력)
// 1 또는 2입니다.


  • 이렇게 case 1:case 2:를 연달아서 지정하면 num1의 값이 1일 때도 코드가 실행되고 2일 때도 코드가 실행된다.
  • 마찬가지로 case 3:case 4:도 연달아서 지정했으므로 num1의 값이 3 또는 4일 때 코드가 실행된다.
  • 즉, case에서 break를 생략하면 여러 가지 값으로 같은 코드를 실행할 수 있다.


  • 위의 코드를 if 조건문과 논리 연산자로도 표현할 수 있다.


if (num1 == 1 || num1 == 2)
    printf("1 또는 2입니다.\n");
else if (num1 == 3 || num1 == 4)
    printf("3 또는 4입니다.\n");
else
    printf("default\n");


  • 하지만 if, else if는 일일이 조건식을 나열해 줘야 하므로 처리해야 할 숫자가 많아지면 매우 번거로워진다.
  • 이런 경우에는 case에서 break를 생략하는 방식이 유용하다.


6. case 안에서 변수 선언하기

  • switchcase에 들어가는 코드가 길어지다 보면 변수를 선언하기도 한다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    int num1;

    scanf("%d", &num1); // 값을 입력받음

    switch (num1) // num1의 값에 따라 분기
    {
    case 1:
        int num2 = num1; // 컴파일 에러 발생
        printf("%d입니다.\n", num2);
        break;
    case 2:
        printf("2입니다.\n");
        break;
    default:
        printf("default\n");
        break;
    }

    return 0;
}


  • Visual Studio 2015에서는 정상적으로 되지만 Visual Studio 2013이하 버전이나 GCC에서는 컴파일 에러가 발생한다.
  • 왜냐하면 case 부분을 {}(중괄호)로 묶어주지 않았기 때문이다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    int num1;

    scanf("%d", &num1); // 값을 입력받음

    switch (num1) // num1의 값에 따라 분기
    {
    case 1:
    { // case에서 변수를 선언하려면 중괄호로 묶어줌
        int num2 = num1;
        printf("%d입니다.\n", num2);
        break;
    }
    case 2:
        printf("2입니다.\n");
        break;
    default:
        printf("default\n");
        break;
    }

    return 0;
}

// 1 (입력)
// 1입니다.


  • 이처럼 case 부분을 {}로 묶어주면 컴파일 에러가 발생하지 않고 변수를 선언할 수 있다.
  • 단, {} 안에 선언된 변수 num2case 1: 안에서만 사용할 수 있고 case 2:switch 바깥에서는 사용할 수 없다.


7. switch에서 판별할 수 있는 자료형 알아보기

  • switch에서 판별할 변수는 정수 자료형만 사용할 수 있고, 실수 자료형은 사용할 수 없다.
  • 단, 문자 자료형도 정수 자료형이므로 switch에서 사용할 수 있다.


#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

int main()
{
    char c1;

    scanf("%c", &c1); // 값을 입력받음

    switch (c1) // c1의 값에 따라 분기
    {
    case 'a': // 문자 a일 때
        printf("a입니다.\n");
        break;
    case 'b': // 문자 b일 때
        printf("b입니다.\n");
        break;
    default: // 아무 case에도 해당되지 않을 때
        printf("default\n");
        break;
    }

    return 0;
}

// a (입력)
// a입니다.


  • switch에서 문자 자료형을 사용해도 정확히 동작한다.
  • 여기서 case에는 숫자 대신 case 'a':처럼 ''(작은따옴표)를 사용하여 문자를 지정해 준다.
  • 단, C에서는 case "Hello":처럼 case에 문자열은 사용할 수 없다.

References