#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지#include<stdio.h>intmain(){intnum1;scanf("%d",&num1);// 값을 입력받음switch(num1)// num1의 값에 따라 분기{case1:// 1일 때printf("1입니다.\n");break;case2:// 2일 때printf("2입니다.\n");break;default:// 아무 case에도 해당되지 않을 때printf("default\n");break;}return0;}// 1 (입력)// 1입니다.
1을 입력했으므로 "1입니다." 문자열이 출력된다.
switch의 ()(괄호) 안에는 먼저 값을 판단할 변수를 지정한다.
여기서는 scanf로 사용자의 입력을 받은 뒤 switch에 num1 변수를 지정했다.
그리고 case로 1일 때, 2일 때 그리고 default로 아무 case에도 해당하지 않을 때 실행할 코드를 지정했다.
switch(num1)// num1의 값에 따라 분기{case1:// 1일 때printf("1입니다.\n");break;case2:// 2일 때printf("2입니다.\n");break;default:// 아무 case에도 해당되지 않을 때printf("default\n");break;}
case 다음에는 반드시 값(리터럴)이 와야 하며 변수나 조건식은 올 수 없다.
그리고 case에 값을 지정했으면 :(콜론)을 붙여준 뒤 다음 줄부터 실행할 코드를 입력한다.
또한, 코드의 마지막에는 break를 입력한다.
이 코드를 switch 분기문 대신 if 조건문으로 표현하면 다음과 같은 모양이 된다.
if(num1==1)// 1일 때printf("1입니다.\n");elseif(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>intmain(){intnum1;scanf("%d",&num1);// 값을 입력받음switch(num1)// num1의 값에 따라 분기{case1:// 1일 때printf("1입니다.\n");case2:// 2일 때printf("2입니다.\n");default:// 아무 case에도 해당되지 않을 때printf("default\n");}return0;}// 1 (입력)// 1입니다.// 2입니다.default
case 1:만 실행될 줄 알았는데 case 2:, default:가 모두 실행되었다.
즉, case를 작성할 때는 마지막 부분에서 break로 중단해 줘야 해당 case만 실행된다.
그러므로 case를 break로 중단하지 않으면 그다음에 있는 case, default가 계속 실행된다.
이런 상황을 Fall Through라고 부른다.
5. case에서 break 생략 응용하기
case에서 break를 생략하는 상황은 버그 같지만 실제로는 많이 사용되는 방식이다.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지#include<stdio.h>intmain(){intnum1;scanf("%d",&num1);// 값을 입력받음switch(num1){case1:// 1 또는case2:// 2일 때 코드 실행printf("1 또는 2입니다.\n");break;case3:// 3 또는case4:// 4일 때 코드 실행printf("3 또는 4입니다.\n");break;default:printf("default\n");}return0;}// 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");elseif(num1==3||num1==4)printf("3 또는 4입니다.\n");elseprintf("default\n");
하지만 if, else if는 일일이 조건식을 나열해 줘야 하므로 처리해야 할 숫자가 많아지면 매우 번거로워진다.
이런 경우에는 case에서 break를 생략하는 방식이 유용하다.
6. case 안에서 변수 선언하기
switch의 case에 들어가는 코드가 길어지다 보면 변수를 선언하기도 한다.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지#include<stdio.h>intmain(){intnum1;scanf("%d",&num1);// 값을 입력받음switch(num1)// num1의 값에 따라 분기{case1:intnum2=num1;// 컴파일 에러 발생printf("%d입니다.\n",num2);break;case2:printf("2입니다.\n");break;default:printf("default\n");break;}return0;}
Visual Studio 2015에서는 정상적으로 되지만 Visual Studio 2013이하 버전이나 GCC에서는 컴파일 에러가 발생한다.
왜냐하면 case 부분을 {}(중괄호)로 묶어주지 않았기 때문이다.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지#include<stdio.h>intmain(){intnum1;scanf("%d",&num1);// 값을 입력받음switch(num1)// num1의 값에 따라 분기{case1:{// case에서 변수를 선언하려면 중괄호로 묶어줌intnum2=num1;printf("%d입니다.\n",num2);break;}case2:printf("2입니다.\n");break;default:printf("default\n");break;}return0;}// 1 (입력)// 1입니다.
이처럼 case 부분을 {}로 묶어주면 컴파일 에러가 발생하지 않고 변수를 선언할 수 있다.
단, {} 안에 선언된 변수 num2는 case 1: 안에서만 사용할 수 있고 case 2:나 switch 바깥에서는 사용할 수 없다.
7. switch에서 판별할 수 있는 자료형 알아보기
switch에서 판별할 변수는 정수 자료형만 사용할 수 있고, 실수 자료형은 사용할 수 없다.
단, 문자 자료형도 정수 자료형이므로 switch에서 사용할 수 있다.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지#include<stdio.h>intmain(){charc1;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;}return0;}// a (입력)// a입니다.
switch에서 문자 자료형을 사용해도 정확히 동작한다.
여기서 case에는 숫자 대신 case 'a':처럼 ''(작은따옴표)를 사용하여 문자를 지정해 준다.