
위에서부터 아래로 순차적(sequence)으로 수행되는 프로그램의 흐름을 제어하는 명령문을 제어문이라고 한다. 그 중 선택 제어문으로는 주어진 조건에 따라 분기점이 나뉘어 특정 부분으로 순서를 옮기는 구조를 만들 수 있다.
if문의 조건이 참일 때는 if문 안의 명령어를, 거짓일 때는 else문 안의 명령어를 수행한다.
⌨️ 예제 1
#include <stdio.h>
int main() {
int a;
scanf("%d", &a);
if(a) {
printf("if문의 조건이 참이 되는 경우\n");
}
else {
printf("if문의 조건이 거짓이 되는 경우\n");
}
}
🖥️ 실행 결과
0 [Enter↵]
if문의 조건이 거짓이 되는 경우
1 [Enter↵]
if문의 조건이 참이 되는 경우
432 [Enter↵]
if문의 조건이 참이 되는 경우
-67 [Enter↵]
if문의 조건이 참이 되는 경우
if문의 조건의 값이 0일 때만 거짓이 되서 else문 안의 내용을 수행하고, 0이 아닌 값은 모두 참이 된다.
⌨️ 예제 2
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
if(n % 2) { // "n % 2"이 0이면 n은 짝수, 1이면 n은 홀수
printf("n은 홀수\n"); // 조건의 값이 1이면 참이 되어 if문 실행
}
else {
printf("n은 짝수\n"); // 조건의 값이 0이면 거짓이 되어 else문 실행
}
}
🖥️ 실행 결과
3 [Enter↵]
n은 홀수
4 [Enter↵]
n은 짝수
if(조건1)문 안에 또 다른 if(조건2)~else문이 중첩된 구조다. (조건1)과 (조건2)가 참이면 바깥쪽 if문 안에 있는 if문을 수행, (조건1)이 참이고 (조건2)가 거짓이면 바깥쪽 if문 안의 else문을 수행한다. (조건1)이 거짓이면 바깥쪽 if와 연결된 else문을 수행하게 된다.
⌨️ 예제 3
/* 입력한 숫자 3개 중 최댓값을 출력하는 프로그램
(컴퓨터는 3중으로 된 연산자를 알아볼 수 없기 때문에 조건들을 분리해야 한다.
예를 들어 "a > b > c"로 작성하면 먼저 앞의 "a > b"를 계산 후,
만약 참이면 1이 되어 "1 > c"를 계산하기 때문에 원하는 결과를 얻을 수 없다) */
#include <stdio.h>
int main() {
int a, b, c; //세 변수의 값이 모두 다르다고 가정
scanf("%d%d%d", &a, &b, &c);
if(a > b) { // "a > b > c", "a > c > b", "c > a > b"가 해당
if(a > c) { // "a > b > c", "a > c > b"가 해당
printf("%d\n", a); // a는 무조건 최댓값이 됨
}
else { // c가 a보다 크므로 "c > a > b"만 해당
printf("%d\n", c); // c가 최댓값이 됨
}
}
else { // "b > a > c", "b > c > a", "c > b > a"가 해당
if(b > c) { // "b > a > c", "b > c > a"가 해당
printf("%d\n", b); // b는 무조건 최댓값이 됨
}
else { // c가 b보다 크므로 "c > b > a"만 해당
printf("%d\n", c); // c가 최댓값이 됨
}
}
}
🖥️ 실행 결과
-7 5 -36 [Enter↵]
5
입력값이 "b > c"이므로 else문 안의 if문이 실행됐다.
조건이 여러 개 있는 다중 선택일 경우에 사용된다. if(조건1)문의 조건1이 거짓이면 그 다음 else if(조건2)문을 검사하는 방식이다. 여러 개의 조건들을 순차적으로 검사하는 도중 하나라도 참이 있으면 해당 명령문을 실행한 후 if~else if~else문으로 연결된 전체가 종료된다. 만약 모든 조건이 전부 거짓일 경우에는 마지막의 else문을 실행한다.
⌨️ 예제 4
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
if(n > 0) { // 조건 1 (거짓일 경우 조건 2 검사)
printf("n은 양수\n");
}
else if(n == 0) { // 조건 2 (거짓일 경우 조건 3 검사)
printf("n은 0\n");
}
else if(n == -5) { // 조건 3 (거짓일 경우 else문 실행)
printf("n은 -5\n");
}
else { // 모든 조건이 거짓일 경우
printf("n은 -5가 아닌 음수\n");
}
}
🖥️ 실행 결과
5 [Enter↵]
n은 양수
⌨️ 예제 5
/* 예제 3을 간략하게 바꾼 코드
1. 중괄호 안에 실행할 명령문이 1개 뿐이면 중괄호 생략 가능
2. 줄바꿈 없이 그대로 이어서 작성
3. else문 안에 if문 중첩 대신 else if문 사용하여 코드 단축
4. else if문, else문은 앞에 있는 제어문의 중괄호 바로 뒤에 작성 가능
경우에 따라 가독성이 떨어질 수 있으니 상황에 맞게 사용해야 함 */
#include <stdio.h>
int main() {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(a > b) { // 중괄호 생략 불가능
if(a > c) printf("%d\n", a); // 중괄호와 줄바꿈 없이 한 줄에 작성
else printf("%d\n", c);
} else if(b > c) printf("%d\n", b); // if문 중괄호 뒤에 바로 else if문 작성
else printf("%d\n", c);
}
🖥️ 실행 결과
3 44 9 [Enter↵]
44
입력값이 "b > c"이므로 else if문이 실행됐다. else문 안에 if문이 들어있는 구조를 else if문으로 바꿔도 똑같이 동작한다는 것을 알 수 있다.
⌨️ 예제 6
/* 시험점수를 입력하면 학점을 출력하는 프로그램
90~100점 : A
80~89점 : B
70~79점 : C
60~69점 : D
50~59점 : E
50점 미만 : F */
#include <stdio.h>
int main() {
int score;
scanf("%d", &score);
// if문 조건을 "score >= 90 && score <= 100"으로 시작하는 것보다 깔끔함
if(score > 100 || score < 0) // 허용 범위 밖의 숫자부터 정의
printf("잘못된 입력값입니다.\n");
else if(score >= 90) // 100점 초과는 이미 걸러졌으므로 90점 이상만 체크
printf("A\n");
else if(score >= 80)
printf("B\n");
else if(score >= 70)
printf("C\n");
else if(score >= 60)
printf("D\n");
else if(score >= 50)
printf("E\n");
else
printf("F\n");
}
🖥️ 실행 결과
94 [Enter↵]
A
참과 거짓 2가지 경우만이 아닌 다양한 경우를 처리해야 할 때 switch문을 사용한다. if문으로도 완벽하게 대체는 되지만, 구조가 더 간단하다는 장점이 있다.
⌨️ 예제 7
// if문을 사용해 5가지 경우를 처리하는 예제 작성
#include <stdio.h>
int main() {
int choice;
printf("새 게임 : 1\n");
printf("불러오기 : 2\n");
printf("설정 : 3\n");
printf("크레딧 : 4\n");
scanf("%d", &choice);
if(choice == 1)
printf("새 게임을 시작합니다\n");
else if(choice == 2)
printf("세이브 파일을 불러옵니다\n");
else if(choice == 3)
printf("설정\n");
else if(choice == 4)
printf("크레딧\n");
else
printf("잘못된 입력입니다\n");
}
🖥️ 실행 결과
새 게임 : 1
불러오기 : 2
설정 : 3
크레딧 : 4
1 [Enter↵]
새 게임을 시작합니다
switch문의 수식으로는 연산식이나 특정 변수가 사용되며, 문자를 포함한 정수형만 가능하다(if문처럼 논리형 값은 사용 불가). 수식의 값과 일치하는 case문을 찾으면 해당 명령문을 수행하며, 해당되는 case문이 하나도 없다면 default문의 명령문을 수행한다(else와 같은 기능을 하며, 생략 가능).
유의해야할 점
⌨️ 예제 8
// 예제 7을 if문 대신 switch문으로 변경
// 먼저 break문이 없으면 어떤 결과가 나오는지 확인해 보기
#include <stdio.h>
int main() {
int choice;
printf("새 게임 : 1\n");
printf("불러오기 : 2\n");
printf("설정 : 3\n");
printf("크레딧 : 4\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("새 게임을 시작합니다\n");
case 2:
printf("세이브 파일을 불러옵니다\n");
case 3:
printf("설정\n");
case 4:
printf("크레딧\n");
default:
printf("잘못된 입력입니다\n");
}
}
🖥️ 실행 결과
새 게임 : 1
불러오기 : 2
설정 : 3
크레딧 : 4
2 [Enter↵]
세이브 파일을 불러옵니다
설정
크레딧
잘못된 입력입니다
case 2 값에 해당하는 경우만 실행되는 것이 아닌 case 2부터 마지막까지 모든 경우가 전부 실행됐다.
🛠️ 코드 수정
// break문을 올바르게 사용
#include <stdio.h>
int main() {
int choice;
printf("새 게임 : 1\n");
printf("불러오기 : 2\n");
printf("설정 : 3\n");
printf("크레딧 : 4\n");
scanf("%d", &choice);
switch(choice) {
case 1:
printf("새 게임을 시작합니다\n");
break;
case 2:
printf("세이브 파일을 불러옵니다\n");
break;
case 3:
printf("설정\n");
break;
case 4:
printf("크레딧\n");
break;
default:
printf("잘못된 입력입니다\n");
break; // default문에는 break문이 필요 없지만 형식상 작성
}
}
🖥️ 실행 결과
새 게임 : 1
불러오기 : 2
설정 : 3
크레딧 : 4
3 [Enter↵]
설정
goto문을 사용하면 현재 위치에서 무조건 원하는 곳으로 실행 순서를 옮길 수 있다. goto문이 유용할 때도 가끔 있지만, 보통은 실행 순서가 복잡하게 꼬여서 스파게티 코드가 되기 십상이기 때문에 가능하면 사용하지 않는 것이 권장된다.
⌨️ 예제 9
// 예제 8을 goto문을 이용해 숫자를 잘못 입력했을 경우 다시 선택창으로 돌아가도록 수정
#include <stdio.h>
int main() {
int choice;
makeChoice : // "Label :" 형식으로 실행이 옮겨질 곳을 지정
printf("새 게임 : 1\n");
printf("불러오기 : 2\n");
printf("설정 : 3\n");
printf("크레딧 : 4\n");
scanf("%d", &choice);
switch(choice) {
case 1: printf("새 게임을 시작합니다\n");
break;
case 2: printf("세이브 파일을 불러옵니다\n");
break;
case 3: printf("설정\n");
break;
case 4: printf("크레딧\n");
break;
default: printf("잘못된 입력입니다\n");
goto makeChoice; // 'makeChoice'라는 라벨이 있는 곳으로 이동함
break;
}
}
🖥️ 실행 결과
새 게임 : 1
불러오기 : 2
설정 : 3
크레딧 : 4
9 [Enter↵]
잘못된 입력입니다
새 게임 : 1
불러오기 : 2
설정 : 3
크레딧 : 4
3 [Enter↵]
설정