본문 바로가기

switch 문 switch statement 본문

💘 C++/흐름제어

switch 문 switch statement

Hyonii 2022. 4. 24. 18:31

switch 문 (switch statement)

if 문과 비슷하게 조건을 다룬다

switch 문은 if문 보다 훨씬 간결하고 깔끔하게 코딩을 할 수 있다는 장점이 있다.

 

switch 문에 대한 개념은 간단하다.

switch 표현식이 값을 평가하고, 각 case 레이블의 값과 '같은'지 테스트한다.

레이블의 값과 같으면 레이블 뒤의 명령문을 실행한다.

일치하는 레이블이 없으면 default 뒤의 명령문을 실행한다. (존재하는 경우)

 

이러한 방식으로 구현되기 때문에 switch 문이 if-else 체인보다 일반적으로 더 효율적이다.


Starting a switch

switch 키워드를 사용하여 switch 문을 시작한 다음 평가한 표현식을 사용한다.

일반적으로 이 표현식은 단 하나의 변수이지만 nx + 2 또는 nx - ny와 같이 좀 더 복잡할 수 있다.

이 표현식에 대한 한 가지 제한 사항은 정수 유형(char, short, int, long, long long, enum)으로 평가되어야 한다는 것이다.

부동 소수점 변수 및 기타 비정수유형은 표현식으로 사용할 수 없다.

switch(expression)
{
	//'같음'을 테스트하는 레이블이 들어간다.
}

switch 식 뒤에 블록을 선언한다.

블록 안에는 레이블(label)을 사용하여 '같음'을 테스트하려는 모든 값을 정의한다.

레이블에는 case label과 default label 두 가지 종류가 있다.

 


[EX 1] if문 보다 switch문이 간결하다는 예제

 

enum class로 Colors를 정의해놓고 

컬러의 이름을 출력하는 함수를 만들고 싶을 때

파라미터에는 컬러중 하나가 들어온다.

예를들어 printColorName() 함수를 main에서 호출하고 싶을 수 있다.

 

컬러가 블랙일 때에는 void printColorName 함수에서 문자열로 black을 출력해줘야 하는 구나,

if 문을 써보자 생각 할 수 있다.  

if 문으로 써보면

 

이딴식으로 쓸 수 있다. 하지만 귀찮다

 

이럴 때 switch-case 문을 사용할 수 있다.

 

이렇게 칠 수 있지만

Colors::BLACK 이렇게 하나하나 입력하기 귀찮아진다.

 

이럴때 static_cast<int>로 형변환해서 간단하게 쓸 수 있다.

enum은 

 

 int로 나오니까.


Case label

case 키워드를 사용하여 선언된 다음 상수 표현식이 온다.

상수 표현식은 상수값을 평가하는 표현식이다.

즉, 리터럴(Ex. 5), 열거형(Ex. COLOR_REN) 또는 상수 변수(Ex. const int 자료형인 변수 x) 등이다.

 

case 레이블 다음의 상수 표현식은 switch 키워드 다음의 표현식과 평가된 값이 '같은'지 테스트 된다.

같을 경우, case 레이블 아래의 코드가 실행된다.

주의 : 모든 case 레이블 표현식은 고유한 값으로 평가되어야 한다. 겹치면 안돼

 

Default label

default case라고도 불린다.

default 키워드를 사용하여 선언된다.

이 레이블 아래의 코드는 switch 표현식과 일치하는 case가 하나도 없으면 실행된다.

default 레이블은 선택사항이며 switch 문당 하나만 있을 수 있다.

일반적으로 swtich 문 블록의 마지막 레이블로 선언되지만, 반드시 필요한 것은 아니다.

 


[EX 2]

숫자를 하나 입력받는 예제를 예로 들어보자

입력받은 숫자를 해당하는 문자로 출력하는 코드를 작성해보면

 

이 때 endl; 은 switch 문을 따라 다닌다. zero 다음에 endl; one 다음에 endl; two 다음에 endl; 이렇게

0을 입력했는데

Zero,One,Two 다 나오고 줄 바꿈도 없다.

 

1을 입력했더니

One Two가 나온다.

if 문과는 좀 다르게 case 뒤에 있는 것도 다 실행시킨다.

실행이 된 후 부터 밑으로 계속 실행이 된다.

많이들 실수하는 부분이다.

 

의도적으로 break를 안넣는 경우도 꽤 있다.

예를들어 2를 넣었을 떄 의도적으로 zero one two가 모두 출력되는 프로그램을 짜고 싶었을 수 있다.

만약 입력받은 숫자에 대해서만 올바른 문자를 출력하고 싶다면

break를 넣어주면 된다.

 

말 그대로 break는 여기서 끝내고 나간다는 의미이다.

 

switch case break는 같이 다닌다.

의도적으로 break를 사용하지 않는 경우도 있다는 것 기억하기

이럴 때에는 꼭 주석 달아주기

 


[EX 3] 복잡한 예제 주의사항

 

이 부분에 명령문을 여러개 넣을 수 있다.

이 안에서 함수도 호출할 수 있다.

여기서 조심해야 할 것은 변수 선언도 할 수 있다.

 

이렇게 할 수 있다. 잠시 주석처리 해놓고

이렇게 int b 초기화 까지 해주고 컴파일 하면 오류가 난다.

선언은 할 수 있지만 대입은 할 수 없다.

초기화는 할 수 없다.

메모리 할당이 안된다는 의미.

변수 선언을 하는 것은 괜찮은데 값을 넣어주는 것은 case문 다음에서 할 수 있다는 것 기억하기!

 

그렇다면 case 문 다음에도 변수 선언을 할 수 있을까?

 

이렇게 할 수 있다.

분명 break도 있는데

 

앞에 case 0에서 정의 된 변수 y를 

case 1 에서 사용 할 수 있다.

 

5가 잘 나온다

 

이번에는 caee 0에서 5를 넣어주고 case 1로 가보면

 

빌드 조차 되지 않는다.

 

선언을 case 안에서 해도 밖에 있는 것과 똑같이 작동한다.

 

이렇게 작동한다

case 1 에서도 y에 접근은 할 수 있는데

y에 5를 넣어주는 것(y를 초기화 해주는 것)은 case에서만 된다.

그러니까 case 0 안을 거치지 않은 상태에서는 y에 쓰레기 값이 들어있는 상태 그대로 case 1로 가버린다.

 

차라리 모든 케이스에 대해서 다 사용되는 변수가 있으면 밖에서 정의해놓는 것이 낫다.

 

변수 선언하고 정의하고 사용할 때 가장 잘하는 방법이 

사용되기 직전에 선언하고 사용되는 최소 범위 영역을 넘어가면 사라져버리게 os에 반납하게 작성하는 것이다.

위처럼 블록을 씌우면 블록 밖으로 나가면 Y는 사라진다.

 

굳이 내가 변수를 한두개 만들어서 써야하는 상황이라면

여러개의 문장을 case안에 넣어줘야 하는 상황이면 이것도 block으로 감싸면됨

 

이것은 취향차이이다.

변수를 사용할 때에는 가급적이면 적은 범위에서 사용해야하고

사용하기 직전에 정의해서 사용하는 것이 좋다.


[EX 4] 내가 입력한 값이 0,1,2,3,4,5,6 이 아니라면 ?

 

0부터 1000000까지 모두 case로 해줘야 하는 것은 아니다.

default를 쳐주면 된다.

 

지금 case 문이 0과 1만 정의되어있기 때문에

3을 입력하면 undefined input이 나온다

 

case에 정의가 되지않은 모든 경우에 대해서 default 가 실행시켜 준다.

아주 편리하다

 

default 밑에 break 해주는 사람도 있는데

앞에 case에서 break가 없으면 밑에 문장들이 전부 실행된다.

default밑에는 아무것도 없는 것이 일반적이다.

되는 경우를 다 쓰고 안되는 경우 default르 쓰는 것이 일반적이다.

보통 default는 break가 없어도 크게 문제되지 않는다.

굳이 default 밑에 break를 치는 이유는 break가 필요해서라기 보다는 

어디는 넣고 어디는 안넣고 하다보면 실수 할 수 있어서 넣는것임

 

case 안에 함수도 들어갈 수 있고 if 문이 또 들어갈 수 있다.

하지만 굳이 그렇게 코딩하지는 않는다.

아니면 적어도 if 문이 보이지 않도록 함수로 싸거나

다른 모듈로 묶거나 하는 방식으로 코딩한다.

프로그래머가 너무 고통스럽지 않게 감춰주는식(abstraction)으로 코딩한다.

'💘 C++ > 흐름제어' 카테고리의 다른 글

for 문 for statement  (0) 2022.04.26
do-while 문 do-while statement  (0) 2022.04.26
while 문 while statement  (0) 2022.04.25
goto 문 goto statement  (0) 2022.04.25
if 조건문 if conditional statement  (0) 2022.01.30
Comments