Skip to Content
독학사독학사 2단계C프로그래밍08. 조건문·반복문 제어 구조

이번 문서의 목표: if/else·switch·while/for/do-while·break/continue의 문법과 동작 규칙을 정확히 이해하고, 중첩된 제어문 코드를 변수 값 표로 한 줄씩 추적해 실제 출력 결과를 스스로 예측할 수 있게 된다.

왜 제어 구조가 필요한가

지금까지(06~08편)는 코드가 위에서 아래로 한 줄씩 순서대로 실행되는 경우만 다뤘습니다. 하지만 실제 프로그램은 “조건에 따라 다른 동작을 하거나”, “같은 동작을 여러 번 반복”해야 하는 경우가 대부분입니다. 예를 들어 “입력한 숫자가 짝수면 A, 홀수면 B를 출력”하거나, “1부터 100까지 더한다”는 요구는 순차 실행만으로는 표현할 수 없습니다.

이렇게 프로그램의 실행 순서를 바꾸는 문법을 제어 구조(control structure, 제어 구조)라고 부릅니다. 제어 구조는 크게 두 종류로 나뉩니다.

  • 조건문(conditional statement, 조건문): 조건의 참·거짓에 따라 실행할 코드를 선택합니다. if, else, switch가 여기 속합니다.
  • 반복문(loop statement, 반복문): 조건이 유지되는 동안 같은 코드 블록을 여러 번 실행합니다. while, for, do-while이 여기 속합니다.

쉽게 말하면: 조건문은 “갈림길”이고, 반복문은 “제자리 돌기”입니다. 독학사 C프로그래밍 시험에서는 이 두 가지를 중첩(조건문 안에 반복문, 반복문 안에 조건문)해 코드를 복잡하게 만든 뒤 “이 코드의 출력은?”을 묻는 문제가 가장 흔한 유형입니다.

1. if/else 조건문

정의와 기본 형태

if문은 소괄호 안 조건식이 참(0이 아닌 값)이면 뒤따르는 블록을 실행하고, 거짓(0)이면 건너뜁니다. C에는 별도의 논리형(boolean)이 없어서, 08편에서 배운 것처럼 정수 0은 거짓, 0이 아닌 모든 정수는 참으로 취급됩니다.

if (조건식) { /* 조건식이 참일 때 실행 */ } else if (다른조건식) { /* 위 조건이 거짓이고, 이 조건이 참일 때 실행 */ } else { /* 모든 조건이 거짓일 때 실행 */ }

else ifelse는 선택 사항이며, 여러 개의 else if를 이어 붙일 수 있습니다. 조건은 위에서부터 순서대로 검사하며, 하나라도 참이면 그 블록만 실행하고 나머지는 검사조차 하지 않습니다.

자주 틀리는 점 1 — ===의 혼동

int x = 3; if (x = 5) { printf("참\n"); } else { printf("거짓\n"); }

이 코드는 언뜻 x가 5가 아니므로 “거짓”이 출력될 것 같지만, 실제로는 “”이 출력됩니다. 이유는 if 안의 x = 5가 비교 연산자 x == 5가 아니라 대입 연산자이기 때문입니다. x = 5x에 5를 대입하고, 그 대입식 전체의 값(대입된 값 5)을 반환합니다. if는 이 반환값 5가 0이 아니므로 참으로 판단합니다. 결과적으로 x의 값도 3에서 5로 바뀌어 버립니다. 독학사 시험에서 “오류 찾기” 유형으로 가장 자주 등장하는 함정이 바로 이것입니다.

자주 틀리는 점: if (조건) 안에 등호가 하나만 있으면 대입, 두 개면 비교입니다. 컴파일러는 이 코드를 문법 오류로 잡지 않으므로(대입식도 값을 가지는 유효한 식이라서) 실행해 보기 전까지는 알아채기 어렵습니다.

자주 틀리는 점 2 — 세미콜론 하나로 블록이 사라짐

int score = 90; if (score >= 60); { printf("합격\n"); }
합격

if (score >= 60);처럼 조건식 바로 뒤에 세미콜론을 붙이면, if문은 빈 문장(아무 일도 하지 않는 문장) 하나만을 실행 대상으로 삼고 끝나 버립니다. 뒤이어 나오는 { printf(...); } 블록은 if와 아무 관계 없는 독립된 코드 블록이 되어 조건과 무관하게 항상 실행됩니다. 이 예제는 score가 60 이상이라 우연히 “합격”이 출력되지만, score = 30으로 바꾸면 조건이 거짓인데도 여전히 “합격”이 출력되어 오류가 드러납니다. 시험에서는 조건이 거짓이 되는 값을 넣어 이 함정을 확인하게 만듭니다.

2. switch 조건문과 fallthrough

switch문은 하나의 정수(또는 문자) 표현식 값을 여러 case 값과 비교해 일치하는 지점부터 실행을 시작합니다.

int grade = 2; switch (grade) { case 1: printf("1등급\n"); break; case 2: printf("2등급\n"); case 3: printf("3등급\n"); break; default: printf("등급 없음\n"); }
2등급 3등급

fallthrough — 왜 3등급까지 출력되는가

case 2:에서 printf("2등급\n")를 실행한 뒤 break가 없으므로, 실행 흐름은 멈추지 않고 바로 아래 case 3: 블록으로 그대로 흘러 들어갑니다. 이 현상을 fallthrough(폴스루, 흘러내리기)라고 부릅니다. case 3:에는 break가 있으므로 거기서 switch문을 완전히 빠져나갑니다.

쉽게 말하면: switch의 각 case는 “판단 갈림길”이 아니라 “코드 안의 이정표(label)“에 가깝습니다. break가 없으면 실행이 멈추지 않고 다음 이정표를 그냥 지나쳐 계속 내려갑니다.

자주 틀리는 점: switchif-else처럼 “하나만 실행하고 끝”이 아닙니다. break를 빠뜨리면 의도치 않게 여러 case가 연달아 실행됩니다. 반대로 여러 case를 일부러 겹쳐서 “같은 처리를 묶는” 용도로 fallthrough를 활용하는 경우도 있으므로(예: case 'a': case 'A':처럼 break 없이 두 case를 붙여 같은 동작을 공유), 시험에서는 break의 유무를 한 줄씩 확인해야 합니다. default는 어떤 case와도 일치하지 않을 때 실행되며, 반드시 마지막에 있을 필요는 없지만 관례상 마지막에 둡니다.

3. while / for / do-while 반복문 비교

세 반복문은 모두 “조건이 참인 동안 반복”한다는 점은 같지만, 조건을 언제 검사하는지문법 구조에서 차이가 있습니다.

반복문조건 검사 시점최소 실행 횟수전형적인 사용처
while반복 시작 전0회(조건이 처음부터 거짓이면 한 번도 실행 안 함)반복 횟수를 미리 알 수 없을 때
for반복 시작 전0회반복 횟수를 미리 알 때(카운터 변수 사용)
do-while반복 실행 후1회(무조건 한 번은 실행)최소 한 번은 실행해야 하는 로직(예: 메뉴 입력 반복)
int i = 0; while (i < 3) { printf("%d ", i); i++; }
0 1 2

for문은 “초기식; 조건식; 증감식”을 한 줄에 모아 쓰는 문법이며, 동작은 while문을 재배열한 것과 완전히 같습니다.

for (초기식; 조건식; 증감식) { /* 반복할 코드 */ } /* 위 for문은 아래 while문과 동일하게 동작한다 */ 초기식; while (조건식) { /* 반복할 코드 */ 증감식; }

do-while의 특이점

int n = 10; do { printf("실행됨\n"); } while (n < 5);
실행됨

n이 10이라 n < 5는 거짓인데도 “실행됨”이 한 번 출력됩니다. do-while먼저 블록을 실행한 뒤에 조건을 검사하기 때문입니다. 자주 틀리는 점: do-while은 조건이 거짓이어도 본문이 최소 1회는 반드시 실행된다는 점을 놓치면 출력 예측을 틀립니다. 또한 do { ... } while (조건);에서 마지막에 세미콜론을 반드시 붙여야 하는데, 이를 빠뜨리는 것도 흔한 문법 오류입니다.

4. break와 continue의 차이

breakcontinue는 둘 다 반복문 안에서 흐름을 바꾸지만 동작이 다릅니다.

  • break: 반복문을 즉시 완전히 종료하고 반복문 다음 코드로 넘어갑니다.
  • continue: 현재 반복(iteration, 이터레이션, 한 바퀴)의 나머지 코드만 건너뛰고, 다음 반복 조건 검사(또는 증감식 실행)로 넘어갑니다. 반복문 자체는 끝나지 않습니다.
for (int i = 1; i <= 5; i++) { if (i == 3) { continue; } if (i == 5) { break; } printf("%d ", i); }

이 코드를 표로 한 줄씩 추적하면 다음과 같습니다.

i 값조건 i == 3조건 i == 5printf 실행?다음 동작
1거짓거짓실행(1 출력)i++
2거짓거짓실행(2 출력)i++
3(검사 안 함)건너뜀continue → i++
4거짓거짓실행(4 출력)i++
5거짓(검사 안 함)break → 반복문 종료
1 2 4

자주 틀리는 점: continue가 실행되면 그 아래 남은 코드는 건너뛰지만, 반복문 자체는 종료되지 않고 다음 회차로 이어집니다. i == 3일 때 continue가 실행되어 printf를 건너뛰었지만, i == 5가 되기 전까지는 반복이 계속됩니다. 반면 i == 5에서는 break가 실행되어 그 즉시 반복문을 빠져나가므로 5는 출력되지 않습니다.

5. 중첩 제어문 흐름 추적 — 실전 손코딩 문제

독학사 시험에서 가장 까다로운 유형은 반복문 안에 반복문(중첩 반복문)이 있고, 그 안에 다시 조건문이 있는 경우입니다. 이런 코드는 바깥쪽 변수와 안쪽 변수를 각각 별도의 열로 둔 표를 그려 추적해야 실수 없이 풀 수 있습니다.

for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { if (j > i) { break; } printf("%d", j); } printf("\n"); }
ij 진행j > i가 되는 시점출력되는 한 줄
1j=1(출력) → j=2(2>1, break)j=21
2j=1(출력) → j=2(출력) → j=3(3>2, break)j=312
3j=1(출력) → j=2(출력) → j=3(출력) → j=4(4>3, break)j=4123
1 12 123

해설 흐름: 바깥쪽 fori를 1, 2, 3으로 바꿔가며 안쪽 for를 매번 처음부터 다시 실행시킵니다. 안쪽 forj를 1부터 늘려가며 출력하다가, ji보다 커지는 순간 break안쪽 반복문만 빠져나갑니다(바깥쪽 반복문은 영향받지 않습니다). 이렇게 안쪽 반복이 끝나면 printf("\n")으로 줄을 바꾼 뒤 바깥쪽 i가 다음 값으로 넘어갑니다. 이 패턴이 “삼각형 모양 출력” 문제의 핵심 원리입니다.

자주 틀리는 점: 중첩 반복문에서 breakcontinue자신을 감싸고 있는 가장 가까운 반복문 하나에만 적용됩니다. “안쪽 break가 바깥쪽 반복문까지 끝낸다”고 착각하면 출력 예측이 완전히 틀립니다.

핵심 정리

  • if (조건)의 조건에 등호 하나(=)만 쓰면 대입이 되어 항상 참으로 평가될 수 있다. 비교는 반드시 ==.
  • if 뒤에 실수로 세미콜론을 붙이면 그 뒤 블록은 조건과 무관하게 항상 실행된다.
  • switchbreak가 없으면 다음 case로 fallthrough(흘러내림)한다.
  • while/for는 조건을 먼저 검사(0회 실행 가능), do-while은 실행 후 검사(최소 1회 실행).
  • break는 반복문을 완전히 종료, continue는 현재 회차만 건너뛰고 반복은 계속된다.
  • 중첩 반복문에서 break/continue는 가장 가까운 자기 반복문에만 적용된다.
  • 중첩 제어문의 출력을 예측할 때는 변수마다 열을 나눈 추적표를 그려 한 줄씩 확인한다.

마무리 복습

문제 14지선다
다음 코드의 실행 결과로 옳은 것은?
문제 24지선다
switch문에서 case 블록 끝에 break를 쓰지 않았을 때 나타나는 현상을 가리키는 용어는?
문제 34지선다
do-while문과 while문의 가장 근본적인 차이는 무엇인가?
문제 44지선다
아래 코드를 실행했을 때 출력되는 숫자를 모두 더하면 얼마인가? (for i가 1부터 5까지 증가하며, i가 3이면 continue, i가 5면 break, 그 외에는 i를 출력한다)
문제 54지선다
다음 중 break와 continue의 차이를 옳게 설명한 것은?
문제 64지선다
중첩된 for문에서 안쪽 for문 안에 있는 break가 실행되면 어떤 일이 일어나는가?
문제 74지선다
다음 코드에서 세미콜론의 위치가 만드는 문제를 옳게 설명한 것은? (코드: if 뒤에 조건을 쓰고 바로 세미콜론을 붙인 뒤, 다음 줄에 중괄호로 감싼 출력문을 둔 경우)

참고 자료

Last updated on