Menu

C의 if else: 문법, 예제, 흔한 실수

C가 판단하는 방법: if 문, else, else if 연쇄, 중첩, 그리고 삼항 연산자 - 여기에 참·거짓 규칙(0은 거짓, 나머지는 모두 참)과 조건을 조용히 망가뜨리는 === 버그까지.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

프로그램에 분기가 필요한 이유

지금까지의 모든 프로그램은 1행, 2행, 3행 순으로 곧장 실행되었습니다. 실제 프로그램은 판단을 합니다. 비밀번호가 맞는가? 그 수가 음수인가? 파일이 열렸는가? if 문은 C가 질문을 던지고, 답이 예일 때만 코드를 실행하는 방법입니다.

조건 temperature > 30은 한 번 검사됩니다. 성립하므로 메시지가 출력됩니다. 마지막 줄은 중괄호 바깥에 있으므로 무슨 일이 있어도 출력됩니다. 3118로 바꾸고 다시 실행해 보세요. 첫 번째 메시지는 사라지고 두 번째는 남습니다.

문법: 괄호, 중괄호, 그리고 세미콜론 없음

C의 if는 정해진 모양을 가집니다.

if (condition) {
    // 조건이 0이 아닐 때 실행됨
}

일찍 외워둘 만한 규칙이 세 가지 있습니다. 조건을 감싸는 괄호는 필수입니다. then 키워드는 없습니다. 그리고 닫는 괄호 뒤에 세미콜론이 없습니다. 하나가 잘못 들어가면 문장이 바로 거기서 끝납니다.

// BUG: if는 아무 일도 하지 않고, printf는 항상 실행된다
if (x > 10);
{
    printf("big\n");
}

이 코드는 아무 오류 없이 컴파일됩니다. ;if의 본문이 되는 빈 문장이고, 그 아래의 중괄호는 항상 실행되는 독립된 블록일 뿐입니다. gcc -Wall로 컴파일하면 잡아냅니다.

문장이 하나뿐이라면 중괄호 자체는 선택 사항이지만, 그래도 넣어두세요. 중괄호 없는 if에 나중에 두 번째 줄이 늘어나는 것은 고전적인 버그의 원인입니다. C에서는 들여쓰기가 문장을 묶어주지 않기 때문입니다.

else와 else if

else는 나머지 경로를 제공합니다.

결과가 두 가지를 넘는다면 else if로 연결합니다. C는 각 조건을 순서대로 검사하고 처음으로 성립하는 곳에서 멈춥니다.

여기서는 순서가 대단히 중요합니다. 연쇄는 처음 일치하는 곳에서 멈추므로, 두 번째 검사는 90 미만의 점수만 보게 됩니다. 그래서 score >= 80&& score < 90을 덧붙일 필요가 없습니다. 가장 제한적인 조건에서 가장 느슨한 조건 순으로 연쇄를 작성하세요. 그러지 않으면 모든 값이 첫 번째 분기로 떨어집니다.

마지막 else는 선택 사항입니다. 연쇄가 모든 경우를 다뤄야 한다면 넣으세요. 없다는 것은 "아무것도 일치하지 않으면 아무것도 하지 않는다"는 뜻이고, 그래도 괜찮지만 의도적인 선택이어야 합니다.

참·거짓: 0은 거짓, 나머지는 모두 참

C의 핵심 언어에는 조건에 쓰이는 별도의 불리언 타입이 없습니다. if는 그저 표현식이 0이 아닌지를 물을 뿐입니다.

마지막 두 줄은 규칙의 나머지 절반을 보여줍니다. 비교 연산자는 참이면 1, 거짓이면 0을 만들어내는 평범한 표현식입니다. 그래서 if (5 > 2)가 동작합니다. 실제로는 if (1)인 셈입니다.

이것이 C에서 -3이 참인 이유이기도 합니다. 규칙은 양수가 아니라 0이 아님입니다. 어떤 수가 양수인지 알고 싶다면 if (n)이 아니라 if (n > 0)이라고 쓰세요.

C99는 진짜 bool 타입과 true, false를 담은 <stdbool.h>를 추가했고, 새로 쓰는 코드에서는 이쪽이 더 잘 읽힙니다. 내부적으로는 여전히 10이므로 위 규칙은 하나도 달라지지 않습니다. C의 불리언을 참고하세요.

조건에서 쓰게 될 비교 연산자와 논리 연산자입니다.

==   같다                     &&   논리 AND (양쪽 모두 참)
!=   같지 않다                ||   논리 OR  (한쪽이라도 참)
<    보다 작다                !    논리 NOT
>    보다 크다
<=   작거나 같다
>=   크거나 같다

&&||는 **단축 평가(short-circuit)**를 합니다. a && ba가 거짓이면 b를 절대 평가하지 않고, a || ba가 참이면 b를 절대 평가하지 않습니다. 이는 최적화가 아니라 보장이므로 if (n != 0 && total / n > 5)라고 안전하게 쓸 수 있습니다. n이 0일 때 나눗셈은 실행될 수 없습니다.

=== 버그

C 조건문에서 단연 가장 흔한 실수입니다.

// BUG: x에 5를 대입한 뒤 5(0이 아님)를 검사하므로 항상 실행된다
if (x = 5) {
    printf("x is five\n");
}

C는 표현식 안의 대입을 허용하므로 이 줄은 적법합니다. x5를 저장하고 값 5를 만들어내며, 5는 0이 아닙니다. 그래서 분기는 매번 실행되고, x는 조용히 덮어씌워집니다.

방어책은 두 가지입니다. 첫째, 항상 경고를 켜고 컴파일하세요.

gcc -Wall -Wextra program.c -o program

GCC와 clang 모두 "suggest parentheses around assignment used as truth value"라고 지적합니다. 둘째, 어떤 프로그래머들은 상수를 변수 앞에 씁니다. if (5 == x)처럼 쓰면 오타로 if (5 = x)가 되었을 때 조용한 버그가 아니라 명백한 컴파일 오류가 됩니다. 그 스타일은 취향의 문제이지만, 경고를 켜는 것은 취향의 문제가 아닙니다.

중첩

if 안에 또 다른 if가 들어갈 수 있습니다. 중첩은 앞선 조건이 성립해야만 의미가 생기는 조건을 표현합니다.

두 단계는 읽을 만합니다. 네 단계는 그렇지 않습니다. 중첩이 깊어지면 평탄하게 만들 방법을 찾아보세요. 흔히 &&로 조건을 합치거나, 실패 경우를 먼저 처리하고 일찍 반환하는 방법을 씁니다.

// 더 평탄하게: 예외를 먼저 처리하고, 그다음 본 작업을 한다
if (age < 18)     { printf("Adults only.\n");        return 0; }
if (!hasTicket)   { printf("Please buy a ticket.\n"); return 0; }
printf("Welcome in.\n");

매달린 else (dangling else)

중괄호 없는 if가 다른 if 안에 중첩되어 있을 때, else는 어느 if에 속할까요? C의 규칙은 이렇습니다. else는 아직 짝을 찾지 못한 가장 가까운 if에 붙습니다. 코드가 어떻게 들여쓰기되어 있든 상관없습니다.

// 들여쓰기와 달리, else는 안쪽 if에 속한다
if (a > 0)
    if (b > 0)
        printf("both positive\n");
else
    printf("a is not positive\n");   // 잘못됨 - a > 0이고 b <= 0일 때 실행된다

들여쓰기는 else가 바깥쪽 if와 짝을 이룬다고 말합니다. 컴파일러는 안쪽 것과 짝지어 줍니다. 중괄호는 이 모호함을 완전히 없애며, 이것이 항상 중괄호를 쓰라는 진짜 근거입니다.

if (a > 0) {
    if (b > 0) {
        printf("both positive\n");
    }
} else {
    printf("a is not positive\n");
}

삼항 연산자

분기가 오로지 값 하나를 고르기 위해 존재한다면, 조건 연산자 ? :가 그것을 한 표현식으로 말해 줍니다.

cond ? x : y는 "cond이면 x, 아니면 y"로 읽으세요. 두 분기 중 정확히 하나만 평가되고, 전체가 하나의 값을 만들어냅니다. 그래서 문장으로는 불가능한 자리, 즉 대입의 오른쪽이나 인자 자리에 들어갈 수 있습니다.

단순한 값 선택에만 쓰세요. 중첩된 삼항 연산자(a ? b : c ? d : e)는 적법하지만, 그것이 대신하는 else if 연쇄보다 거의 언제나 읽기 어렵습니다.

자주 묻는 질문

C에서 if else 문은 어떻게 작성하나요?

조건은 괄호 안에, 코드는 중괄호 안에 넣습니다: if (score >= 60) { printf("Pass\n"); } else { printf("Fail\n"); }. else 블록은 조건이 거짓일 때만 실행되며, C에는 then 키워드가 없습니다.

C의 if 문에서 무엇이 참으로 취급되나요?

0이 아닌 모든 값입니다. C의 핵심 문법에는 전용 불리언 타입이 없으므로, if (n)n0만 아니면 실행되고 if (!n)n이 정확히 0일 때만 실행됩니다. ==< 같은 비교 연산자는 참이면 1, 거짓이면 0을 만들어냅니다.

C에서 =와 ==의 차이는 무엇인가요?

==는 비교하고 =는 대입합니다. if (x = 5)라고 쓰면 x5를 대입한 다음 5를 검사하는데, 5는 0이 아니므로 그 분기는 항상 실행됩니다. 오류 없이 컴파일되기 때문에 C 조건문에서 초보자가 가장 흔히 저지르는 버그이며, 대부분의 컴파일러는 -Wall로 이를 경고합니다.

C에서 삼항 연산자는 어떻게 동작하나요?

condition ? valueIfTrue : valueIfFalse는 두 값 중 하나를 만들어내는 표현식이므로 대입문이나 printf 인자 안에 들어갈 수 있습니다: int max = a > b ? a : b;. 값을 고를 때는 이것을 쓰고, 문장을 실행해야 할 때는 보통의 if를 쓰세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기