조건에 따른 분기
if문은 입력에 따라 실행되는 문장이 달라지게 합니다.
갈림길이 없는 프로그램은 위에서 아래로 한 번 실행되고 끝납니다.
입력이 무엇이든 실행되는 문장이 같습니다. if문은 여기에
갈림길을 놓습니다. 이처럼 조건에 따라 실행 흐름이 나뉘는 것을 분기(branch)라고 합니다.
int score = 75;
if (score >= 60) {
printf("합격\n"); // 합격
} else {
printf("불합격\n");
}실행 순서
- 괄호 안의 조건식을 계산한다 — 비교 연산의 결과는 1(참)이나 0(거짓)이다.
- 결과가 0이 아니면 바로 뒤 중괄호 안의 문장을 실행하고,
else부분은 건너뛴다. - 결과가 0이면
else부분만 실행한다.
둘 중 하나만 실행됩니다. else는 생략할 수 있습니다.
생략하면 조건이 거짓일 때 아무것도 실행하지 않고 다음 문장으로 넘어갑니다.
경우가 셋 이상이면 else if로 조건을 이어 씁니다.
int score = 85;
if (score >= 90) {
printf("A\n");
} else if (score >= 80) {
printf("B\n"); // B 여기서 멈춘다
} else if (score >= 70) {
printf("C\n");
} else {
printf("D\n");
}위에서부터 검사하다가 「참인 첫 조건」에서 멈춥니다
85점은 score >= 80도 참이고 score >= 70도 참입니다.
그런데 B만 출력됩니다. 참인 조건을 하나 만나면 그 아래 조건은 검사하지 않기 때문입니다.
그래서 조건의 순서가 결과를 바꿀 수 있습니다. 위 코드에서 조건의 순서를 뒤집어
score >= 70을 맨 위에 두면 95점도 C가 됩니다.
이렇게 조건의 범위가 서로 겹칠 때는 좁은 조건부터 넓은 조건 순으로 써야 합니다.
#include <stdio.h>
int main(void) {
int year;
printf("연도를 입력하세요: ");
scanf("%d", &year);
if (year % 4 == 0 && year % 100 != 0) {
printf("%d년은 윤년입니다.\n", year);
} else if (year % 400 == 0) {
printf("%d년은 윤년입니다.\n", year);
} else {
printf("%d년은 윤년이 아닙니다.\n", year);
}
return 0;
}
윤년 판별은 else if로 조건을 이어 쓰는 좋은 예입니다.
4의 배수이면서 100의 배수가 아니면 윤년이고,
100의 배수라도 400의 배수이면 윤년입니다.
2024와 2000은 윤년이고, 1900은 아닙니다.
스스로 확인
위 등급 코드에 score가 105일 때는 무엇이 출력될까요? 0점부터 100점까지의 범위를 벗어난 값을 처리하려면 어디에 어떤 조건을 추가해야 할까요?
중괄호는 어디까지를 묶는가
들여쓰기는 사람 눈에만 보입니다.
조건이 참일 때 실행할 문장이 하나뿐이면 중괄호를 생략할 수 있습니다. 그런데 중괄호를 생략한 코드에서 찾기 어려운 실수가 자주 생깁니다.
int score = 40;
if (score >= 60)
printf("합격\n");
printf("축하합니다\n"); // if와 상관없이 「언제나」 실행된다
// 들여쓰기는 사람 눈에만 보인다. 중괄호가 없으면 if문에 포함되는 것은 「다음 문장 하나」뿐이다if문에 포함되는 것은 「다음 문장 하나」뿐입니다
두 줄을 똑같이 들여 써서 둘 다 if문에 포함된 것처럼 보이지만, C 컴파일러는 들여쓰기를 무시합니다.
printf("축하합니다")는 조건과 상관없이 언제나 실행됩니다.
40점이어도 「축하합니다」가 출력됩니다.
문법 오류가 아니라 의도와 다른 동작이라 컴파일은 정상적으로 됩니다. 다만 요즘 컴파일러는 경고 옵션을 켜 두면 이런 코드를 찾아 「들여쓰기가 오해를 부른다」는 경고를 냅니다. 경고를 읽는 습관이 있으면 이 실수를 잡을 수 있습니다.
문장이 하나여도 중괄호를 쓰는 편이 낫습니다
중괄호를 생략해도 문법에 어긋나지 않습니다. 다만 나중에 문장을 하나 더 추가할 때 중괄호를 함께 넣는 것을 잊기 쉽고, 그러면 방금 본 실수가 그대로 생깁니다. 처음부터 중괄호를 써 두면 이런 실수가 생기지 않습니다.
스스로 확인
중괄호 없는 if 아래에 문장을 두 개 쓰고, 조건이 참일 때 둘 다 실행되게 하려면 무엇을 고쳐야 할까요?
값으로 고르는 switch문
「크다·작다」가 아니라 「어느 값과 같은가」를 여러 번 비교할 때 씁니다.
grade == 'A', grade == 'B'…처럼
같은 변수가 어느 값과 같은지만 비교할 때는
switch문으로 쓰면 값에 따라 무엇을 실행하는지 한눈에 보입니다.
char grade = 'B';
switch (grade) {
case 'A':
printf("아주 잘했습니다\n");
break;
case 'B':
printf("잘했습니다\n"); // 잘했습니다
break;
case 'C':
printf("보통입니다\n");
break;
default:
printf("모르는 등급입니다\n");
}case뒤에는 고정된 값만 쓸 수 있다.case score > 80:처럼 조건식은 쓸 수 없다.default는 어느case의 값과도 같지 않을 때 실행된다.if문의else에 해당한다.- 비교할 수 있는 것은 정수와 문자다. 실수와 문자열에는 쓸 수 없다.
break가 없으면 아래 case로 이어서 실행됩니다
int menu = 1;
switch (menu) {
case 1:
printf("하나\n"); // 하나
case 2:
printf("둘\n"); // 둘 break가 없어 아래 case로 이어서 실행된다
case 3:
printf("셋\n"); // 셋
}
case는 실행을 시작할 위치만 정하고, 끝낼 위치는 정하지 않습니다.
값이 같은 case에서 실행을 시작하면 break를 만나거나 switch문이 끝날 때까지
아래 case의 문장들도 차례로 실행됩니다.
참인 조건 하나만 실행하고 멈추는 else if와 다른 점입니다.
이것은 결함이 아니라 일부러 활용하기도 하는 동작입니다.
예를 들어 여러 값에 같은 문장을 실행하려면 break 없이 case를 이어 씁니다.
다만 break를 실수로 빠뜨린 것인지 일부러 뺀 것인지 코드만 봐서는 알 수 없으므로,
일부러 뺄 때는 주석으로 밝혀 둡니다.
if문과 switch문 가운데 무엇을 쓸까
switch문으로 쓴 것은 모두 if문으로 바꿔 쓸 수 있습니다.
반대는 성립하지 않습니다. 범위를 검사하는 조건은 case 뒤에 그대로 쓸 수 없고, 실수를 비교하는 조건은 switch문으로 나타낼 수 없기 때문입니다.
정해진 값 가운데 하나를 고르는 경우라면 switch문이 읽기 쉽고,
범위를 검사하거나 여러 변수를 함께 비교하는 경우라면 if문을 씁니다.
스스로 확인
점수 90점 이상이면 A, 80점대면 B…를 switch문으로 쓰려면 무엇이 곤란할까요?
값 하나를 고르는 조건 연산자
조건에 따라 달라지는 것이 「실행할 문장」이 아니라 「값」일 때가 있습니다.
int score = 75;
// 조건 ? 참일 때 값 : 거짓일 때 값
printf("%s\n", score >= 60 ? "합격" : "불합격"); // 합격
int big = 3 > 5 ? 3 : 5;
printf("%d\n", big); // 5조건 연산자(conditional operator)
조건 ? 참일 때 값 : 거짓일 때 값 형식으로 씁니다. 연산에 쓰이는 값(피연산자)이 셋이라 삼항 연산자라고도 합니다.
if문이 실행할 문장을 고르는 것과 달리 조건 연산자는 값을 고릅니다.
그래서 대입문의 오른쪽이나 printf로 출력할 값처럼
값이 들어갈 곳에 바로 쓸 수 있습니다.
짧다고 늘 나은 것은 아닙니다. 고르는 것이 값 하나이고 조건이 짧을 때는
한 줄로 읽기 좋지만, 조건 연산자 안에 또 조건 연산자를 넣으면 금세 읽기 어려워집니다.
그럴 때는 if문으로 풀어 쓰는 편이 낫습니다.
스스로 확인
n이 -7일 때 int m = n < 0 ? -n : n;을 실행하면 m에는 무엇이 저장될까요? n이 4일 때와 비교해 보고, 이 식이 어떤 값을 구하는지 말해 보세요.
핵심 정리
if · else if
위에서부터 조건을 검사하다가 참인 첫 조건에서 멈춘다. 조건의 범위가 겹치면 순서가 결과를 바꾸므로 좁은 조건을 위에 놓는다.
중괄호
중괄호가 없으면 다음 문장 하나만 if문에 포함된다.
C는 들여쓰기를 무시한다. 문장이 하나여도 중괄호를 쓰는 편이 안전하다.
switch
변수를 정해진 값과 비교할 때 쓴다. case는 실행을 시작할 위치만 정하므로
break가 없으면 아래 case로 이어서 실행된다.
case 뒤에 범위 조건은 쓸 수 없다.
조건 연산자
조건 ? 값 : 값. 실행할 문장이 아니라 값을 고른다.
안에 또 조건 연산자를 넣으면 읽기 어려우므로 그때는 if문으로 풀어 쓴다.
확인 퀴즈
배운 내용을 확인해 봅시다.
1. score가 95일 때, 조건을 score >= 70 → score >= 80 →
score >= 90 순서로 두고 else if로 이어 쓰면 어떻게 실행되는가?
2. switch에서 break를 빠뜨리면?
3. 다음 중 틀린 설명은?