switch-case 관통(fall-through)·while/do-while 차이·break·continue 흐름을 변수 상태표로 정확히 추적하는 법
🎯 학습 목표
이 강을 마치면 중첩된 if-else 구조, switch-case의 관통(fall-through) 동작, for·while·do-while 반복문의 실행 횟수, break·continue가 흐름을 어떻게 바꾸는지를 코드만 보고 손으로 정확히 추적할 수 있습니다. 지난 강에서 다진 자료형·연산자 지식 위에 제어문이 더해지면, 실기 시험에 실제로 나오는 형태의 복잡한 코드 추적 문제를 풀 수 있는 기본기가 완성됩니다. 이번 강은 이 시리즈에서 가장 많은 배점을 차지하는 유형인 "출력 결과를 쓰시오" 문제를 정면으로 다루는 강의이므로, 예제를 눈으로만 읽지 말고 직접 손으로 값을 적어가며 따라오시기 바랍니다.
📌 제어문 추적이 실기 합격을 가르는 이유
이 섹션에서는 왜 제어문 추적 능력이 실기 시험의 당락을 좌우하는지 살펴보겠습니다. 정보처리기사 실기의 프로그래밍 언어 문항은 대부분 짧은 프로그램 하나를 주고 최종 출력값을 적으라는 형태로 출제됩니다. 자료형과 연산자만으로 구성된 코드는 길어야 서너 줄이지만, 조건문과 반복문이 섞이면 코드가 열 줄, 스무 줄로 늘어나면서 변수 값이 매 반복마다 바뀌게 됩니다. 이 상태 변화를 중간에 하나라도 놓치면 최종 출력값이 완전히 달라지기 때문에, 제어문 추적은 "이해했다"와 "정답을 맞혔다" 사이의 간극이 가장 크게 벌어지는 영역입니다.
특히 반복문 안에 조건문이 중첩되고, 조건문 안에서 반복 변수가 바뀌는 형태의 코드는 눈으로 훑어서는 정확한 값을 알 수 없습니다. 이런 문제를 풀 때 가장 확실한 방법은 변수 상태표를 손으로 그리는 것입니다. 반복이 몇 번 도는지, 각 반복에서 변수가 어떤 값으로 바뀌는지를 표로 옮기면서 따라가면 아무리 복잡한 코드도 기계적으로 정답에 도달할 수 있습니다. 이번 강에서는 이 변수 상태표 그리는 습관을 여러 예제를 통해 반복적으로 연습하겠습니다.
💡 조건문 — if-else 중첩과 switch-case 관통
이 섹션에서는 조건문의 두 축인 if-else와 switch-case를 자세히 살펴보겠습니다. if-else는 조건식이 참(0이 아닌 값)이면 if 블록을, 거짓(0)이면 else 블록을 실행하는 가장 기본적인 분기 구조입니다. if-else가 중첩되면 바깥쪽 조건부터 순서대로 평가되며, 어떤 else가 어떤 if에 짝지어지는지를 정확히 파악해야 합니다. C언어에서는 else가 가장 가까운, 아직 else가 없는 if와 짝을 이룬다는 규칙이 있으므로, 들여쓰기만 보고 판단하지 말고 이 규칙으로 짝을 다시 확인하는 습관이 필요합니다.
switch-case는 하나의 정수(또는 문자) 값을 여러 case와 비교해서 일치하는 지점부터 실행을 시작하는 구조입니다. 여기서 실기 시험의 단골 함정은 관통(fall-through) 동작입니다. C언어의 switch-case는 일치하는 case를 찾으면 그 지점부터 실행을 시작할 뿐, 각 case 블록이 자동으로 끝나지 않습니다. 즉 break 문을 만나거나 switch 블록이 끝날 때까지 그 아래에 있는 모든 case의 코드를 순서대로 계속 실행합니다. 이 동작을 모르면 case 하나만 실행되고 멈출 것이라고 착각해서 오답을 적게 됩니다.
#include <stdio.h>
int main() {
int score = 2;
switch (score) {
case 1:
printf("A");
case 2:
printf("B");
case 3:
printf("C");
break;
case 4:
printf("D");
default:
printf("E");
}
return 0;
}
이 코드를 추적해보겠습니다. score가 2이므로 case 2부터 실행이 시작되어 "B"가 출력됩니다. 그런데 case 2 블록에는 break가 없으므로 실행이 멈추지 않고 바로 아래 case 3로 관통해 "C"가 출력됩니다. case 3에는 break가 있으므로 여기서 switch 블록을 완전히 빠져나갑니다. 따라서 최종 출력은 "BC"입니다. 만약 case 3에도 break가 없었다면 case 4와 default까지 관통해서 "BCDE"가 출력되었을 것입니다. 이렇게 break가 있는지 없는지를 case마다 하나하나 확인하는 것이 switch-case 문제를 정확히 푸는 핵심입니다.
💻 반복문 — for·while·do-while과 break·continue
이 섹션에서는 세 가지 반복문의 차이와, 반복 흐름을 중간에 바꾸는 break·continue를 살펴보겠습니다. for문은 for(초기식; 조건식; 증감식) 형태로, 초기식이 한 번 실행된 뒤 조건식이 참인 동안 본문과 증감식을 반복합니다. while문은 조건식만 있는 형태로, 조건이 참인 동안 본문을 반복하되 조건을 먼저 검사한 뒤 본문을 실행하므로 조건이 처음부터 거짓이면 본문이 한 번도 실행되지 않을 수 있습니다. 반면 do-while문은 본문을 먼저 한 번 실행한 뒤 조건을 검사하므로, 조건이 거짓이더라도 본문이 최소 한 번은 반드시 실행된다는 점이 while과의 결정적인 차이입니다.
#include <stdio.h>
int main() {
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue;
}
if (i == 9) {
break;
}
sum += i;
}
printf("%d\n", sum);
return 0;
}
이 코드를 변수 상태표로 추적해보겠습니다. i가 1부터 10까지 증가하는 for문 안에서, 먼저 i가 짝수인지 검사해 짝수면 continue로 그 다음 반복으로 즉시 넘어갑니다. continue는 반복문을 완전히 빠져나가는 것이 아니라, 본문의 나머지 부분을 건너뛰고 다음 반복(for문에서는 증감식 실행 후 조건 재검사)으로 넘어간다는 점이 break와 다릅니다. i가 1일 때는 홀수이고 9도 아니므로 sum에 1이 더해져 1이 됩니다. i가 2일 때는 짝수이므로 continue로 건너뜁니다. 같은 방식으로 i가 3, 5, 7일 때 각각 sum에 더해져 1+3+5+7=16이 됩니다. i가 9가 되면 홀수이면서 동시에 9이므로 break를 만나 반복문을 완전히 종료합니다. 따라서 sum에 9는 더해지지 않고, 최종 출력값은 16입니다.
여기서 break와 continue의 차이를 명확히 구분하는 것이 매우 중요합니다. break는 자신이 속한 반복문(또는 switch문) 자체를 완전히 종료시켜 반복문 다음 코드로 실행이 넘어가고, continue는 현재 반복만 건너뛰고 반복문 자체는 계속 진행됩니다. 중첩 반복문에서는 break와 continue 모두 자신을 감싸고 있는 가장 안쪽 반복문에만 영향을 미친다는 점도 함께 기억해두어야 합니다. 바깥쪽 반복문까지 한 번에 빠져나가는 문법은 C언어에 별도로 존재하지 않으므로, 이런 동작이 필요한 코드에서는 별도의 플래그 변수나 goto가 쓰이기도 합니다.
⚠️ 자주 하는 실수와 주의점
이 섹션에서는 제어문 문제에서 반복적으로 나타나는 실수 패턴을 짚어보겠습니다. 첫 번째는 switch-case에서 break 누락을 놓치고 case 하나만 실행된다고 착각하는 것입니다. 문제에 break가 없는 case가 나오면 반드시 그 아래 case까지 계속 실행된다는 사실을 의심 없이 적용해야 합니다. 두 번째는 while과 do-while을 혼동해서, 조건이 처음부터 거짓인 do-while 문제에서 본문이 실행되지 않는다고 잘못 판단하는 것입니다. do-while은 조건과 무관하게 최소 한 번은 실행된다는 점을 반드시 기억해야 합니다.
세 번째는 for문의 반복 횟수를 셀 때 조건식의 등호 유무를 놓치는 것입니다. i < 10과 i <= 10은 반복 횟수가 하나 차이 나므로, 조건식을 정확히 읽지 않으면 오답으로 이어집니다. 네 번째는 중첩 반복문에서 break가 바깥쪽 반복문까지 종료시킨다고 착각하는 것입니다. break는 자신이 속한 가장 안쪽 반복문만 종료시키므로, 바깥쪽 반복문은 계속 다음 반복을 진행합니다. 다섯 번째는 else가 어느 if와 짝을 이루는지를 들여쓰기만 보고 판단하는 것입니다. 실제 시험 문제는 들여쓰기가 코드의 논리 구조와 일부러 다르게 인쇄되어 혼동을 유도하는 경우가 있으므로, 반드시 "가장 가까운 else 없는 if"라는 규칙으로 다시 확인해야 합니다.
🚀 심화 — 변수 상태표로 복잡한 코드 정복하기
이 섹션에서는 여러 제어문이 중첩된 복잡한 코드를 실수 없이 추적하는 실전 방법을 정리하겠습니다. 반복문이 두 겹 이상 중첩되거나, 반복문 안에 조건문이 여러 개 섞인 코드는 머릿속 계산만으로 정확히 추적하기 어렵습니다. 이럴 때는 답안지 여백에 표를 그려, 가로줄에는 반복 횟수를, 세로줄에는 각 변수의 이름을 적고 매 반복마다 값이 바뀔 때 칸을 채워나가는 방법이 가장 확실합니다. 이 방법은 시간이 조금 더 걸리지만, 암산으로 틀리는 실수를 원천적으로 막아주기 때문에 정확한 값과 표기를 요구하는 실기 시험에서 특히 유리합니다.
또한 중첩 반복문 문제를 만나면 안쪽 반복문 전체가 한 번 도는 동안 바깥쪽 반복 변수는 값이 바뀌지 않는다는 점을 기준으로 삼아, 안쪽 반복문부터 독립적으로 먼저 계산한 뒤 그 결과를 바깥쪽 반복에 대입하는 순서로 접근하면 계산이 훨씬 단순해집니다. 예를 들어 구구단처럼 바깥쪽이 단(2~9), 안쪽이 곱하는 수(1~9)로 중첩된 코드라면, 바깥쪽 값 하나를 고정한 상태에서 안쪽 반복문이 몇 번 도는지와 각 반복에서 무엇이 출력되는지를 먼저 확정한 뒤, 바깥쪽 값을 하나씩 바꿔가며 같은 과정을 반복하는 식입니다. 이 접근법은 다음 강에서 다룰 배열·문자열 순회 코드에도 그대로 이어지므로 지금 확실히 익혀두는 것이 중요합니다.
📝 핵심 요약
- switch-case는 break가 없으면 그 아래 case까지 계속 실행되는 관통(fall-through) 동작을 합니다.
- while은 조건을 먼저 검사해 거짓이면 한 번도 실행되지 않을 수 있지만, do-while은 조건과 무관하게 본문이 최소 한 번 실행됩니다.
- break는 자신이 속한 가장 안쪽 반복문(또는 switch)을 완전히 종료시키고, continue는 현재 반복만 건너뛰고 반복문은 계속됩니다.
- else는 들여쓰기가 아니라 "가장 가까운, 아직 else가 없는 if"와 짝을 이룹니다.
- 복잡한 중첩 코드는 암산 대신 변수 상태표를 손으로 그려가며 추적하는 것이 실수를 줄이는 가장 확실한 방법입니다.
다음 강에서는 이번 강에서 다진 반복문 감각을 그대로 활용해, 배열과 문자열을 순회하며 값을 읽고 쓰는 코드의 출력 결과를 추론하는 방법을 다루겠습니다.
📚 참고 자료
관련 주제
- switch case
- fall-through
- do-while
- break continue
- for문
- 중첩 반복문
- if else 중첩
- 변수 상태표
- 자격증
- 자격증 강의
- 정보처리기사 실기 완전정복 40강
- NUGUNA
- 누구나
📚 시리즈 전체 공유
정보처리기사 실기 완전정복 40강
이 강의가 속한 시리즈는 총 40강(수강생 전용 보너스 · 1~3강 무료)입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.
댓글
불러오는 중...
