본문으로 건너뛰기

반복문과 추적 표

정보처리기사 목차프로그래밍 기초레슨 129 / 233

목차

반복문(loop statement)은 조건이 참인 동안 같은 덩어리를 되풀이하는 문장입니다. 같은 일을 여러 번 할 때 코드를 한 번만 씁니다. 시험은 몇 번 도는지와 끝난 뒤의 값·출력을 묻는데, 머리로만 따라가면 한 바퀴를 놓치기 쉬워 손으로 추적 표를 씁니다. 아래 그림은 for 머리의 세 칸과 몸이 실행되는 차례를 한 줄씩 보입니다.

11단계 중 1단계. 이 그림 읽는 법: 줄이 하나 실행될 때마다 추적 표에 한 줄을 적습니다. 4번 줄 — s에 0을 넣습니다. i는 아직 값을 넣지 않았습니다.

1for 머리의 세 칸 — 시작; 조건; 한 바퀴 뒤

for (시작; 조건; 한 바퀴 뒤)의 시작 칸은 처음 한 번, 조건 칸은 바퀴마다 몸 앞에서, 한 바퀴 뒤 칸은 몸이 끝날 때마다 실행됩니다. 조건이 거짓이 되는 순간 반복이 끝나므로, 끝난 뒤 i는 조건을 처음 어긴 값입니다.

머리몸을 도는 i끝난 뒤 i
for (i = 1; i <= 3; i++)1 2 34
for (i = 0; i < 3; i++)0 1 23
for (i = 10; i > 1; i /= 2)10 5 21

중괄호가 없으면 for·if의 몸은 바로 다음 한 문장입니다. for가 두 겹이면 바깥 for의 몸은 안쪽 for 문장 하나이고, 안쪽 for는 바깥 한 바퀴마다 처음부터 다시 돕니다(알고리즘과 시간 복잡도 예제가 이 꼴입니다).

2while·do-while과 break·continue

while (조건)은 시작 칸과 한 바퀴 뒤 칸이 없는 for와 같습니다. do { … } while (조건);은 몸을 먼저 실행하고 끝에서 조건을 보므로, 조건이 처음부터 거짓이어도 한 번은 돕니다. a가 5일 때 while (a < 3) a++;는 한 번도 돌지 않지만, do a++; while (a < 3);⁠는 한 번 돌아 a가 6입니다.

break는 반복을 바로 끝내고, continue는 이번 바퀴의 남은 문장만 건너뜁니다. for에서 continue 다음에는 한 바퀴 뒤 칸이 실행됩니다. break로 끝나면 한 바퀴 뒤 칸도 조건도 거치지 않아, 반복 변수는 break를 만난 바퀴의 값에 남습니다.

3손으로 쓰는 추적 표

추적 표(trace table)는 실행되는 줄마다 줄 · 바뀐 이름 · 값 · 출력을 한 줄씩 적는 표입니다. 조건 칸도 한 줄로 적고, 값이 바뀌지 않는 줄도 건너뛰지 않습니다. 그림의 코드는 한 바퀴 뒤 칸이 i += 2라 i가 2씩 늘어납니다.

#include <stdio.h>

int main(void) {
  int i, s = 0;
  for (i = 1; i <= 3; i += 2) {
    s += i;
  }
  printf("%d %d\n", i, s);
  return 0;
}
실행 결과
5 4

이 코드를 끝까지 적으면 이렇습니다.

줄바뀐 이름값출력
4s0
5i1
5조건 i <= 3참
6s1
5i3
5조건 i <= 3참
6s4
5i5
5조건 i <= 3거짓
85 4

조건이 거짓인 줄에서 반복이 끝나고, 참인 줄 수가 반복 횟수입니다. 출력 칸을 위에서 아래로 읽으면 실행 결과입니다.

예제

중괄호 없는 두 겹 for입니다. 찍힐 값을 먼저 세어 보세요.

#include <stdio.h>

int main(void) {
  int i, j, c = 0;
  for (i = 1; i <= 3; i++)
    for (j = i; j <= 3; j++)
      c++;
  printf("%d %d %d\n", i, j, c);
  return 0;
}
실행 결과 보기
실행 결과
4 4 6

안쪽 for는 바깥 한 바퀴마다 j = i부터 다시 시작합니다.

바깥 i안쪽 jc가 늘어난 수
11 2 33
22 32
331

c는 3 + 2 + 1로 6입니다. 마지막 안쪽 반복은 j가 4에서 끝났고, 바깥 반복은 i가 4에서 끝났습니다.

같은 코드를 Java·Python으로

C · JavaPython
forfor (i = 1; i <= 3; i++)for i in range(1, 4):
끝난 뒤 i43 — range의 마지막 값
do-while있음없음
s = 0
for i in range(1, 4):
    s += i
print(i, s)
실행 결과
3 6

시험 포인트

  • 필기: for는 시작 한 번 → 조건 → 몸 → 한 바퀴 뒤 → 조건 차례로 돌고, 조건이 거짓이 되어 끝난 뒤 반복 변수는 조건을 처음 어긴 값입니다(break로 나오면 그 바퀴의 값). do-while은 조건이 거짓이어도 몸을 한 번 실행합니다. 반복 횟수를 고르는 문제가 많습니다.
  • 실기: 출력을 그대로 씁니다. 바퀴마다 추적 표에 적어 한 바퀴도 놓치지 않습니다. 빈칸에 쓰는 키워드는 break·continue·do입니다.

확인 문제

1. 몸이 세 번 실행되는 것을 고르세요. i는 int입니다.

  • ① for (i = 0; i <= 3; i++)
  • ② for (i = 16; i > 2; i /= 2)
  • ③ i = 4; while (i < 3) i++;
  • ④ i = 7; do i++; while (i < 3);
정답

②입니다. i가 16·8·4일 때 몸을 돌고, 2가 되면 2 > 2가 거짓이라 끝납니다.

  • ① i가 0·1·2·3으로 네 번입니다. <=라 3도 돕니다.
  • ③ 4 < 3이 처음부터 거짓이라 한 번도 돌지 않습니다.
  • ④ do-while은 몸을 먼저 실행해 한 번 돌고, 8 < 3이 거짓이라 끝납니다.

2. 예제 코드의 5번 줄에서 i <= 3을 i < 3으로 바꿨습니다. 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

#include <stdio.h>

int main(void) {
  int i, j, c = 0;
  for (i = 1; i < 3; i++)
    for (j = i; j <= 3; j++)
      c++;
  printf("%d %d %d\n", i, j, c);
  return 0;
}
정답

받는 답:

실행 결과
3 4 5

바깥 반복은 i가 1·2일 때만 돌아, c는 3 + 2로 5입니다. i는 3에서 조건이 거짓이 되어 끝납니다. j는 마지막으로 돈 안쪽 반복(i가 2일 때)이 4에서 끝난 값입니다.

  • 틀리는 꼴 3 3 5: 안쪽 반복이 끝난 뒤 j가 마지막으로 몸을 돈 3에 남는다고 봤습니다. j도 조건을 처음 어긴 4입니다.
  • 틀리는 꼴 4 4 6: i가 3인 바퀴까지 셌습니다. 3 < 3은 거짓이라 바깥 반복은 i가 3에서 끝납니다.

3. 다음 코드를 바퀴마다 줄여 적은 추적 표입니다. (가)~(다)를 채운 뒤 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

i조건 i == 2한 일s
1거짓s += i1
2참continue(가)
3(나)s += i4
4거짓s += i(다)
#include <stdio.h>

int main(void) {
  int i, s = 0;
  for (i = 1; i <= 4; i++) {
    if (i == 2) {
      continue;
    }
    s += i;
  }
  printf("%d %d\n", i, s);
  return 0;
}
정답

(가) 1 · (나) 거짓 · (다) 8이고, 출력은 다음과 같습니다.

실행 결과
5 8

i가 2인 바퀴는 continue가 9번 줄을 건너뛰어 s가 1 그대로입니다. continue 다음에는 i++가 실행되어 반복이 이어집니다. i가 5가 되면 5 <= 4가 거짓이라 끝납니다.

  • 틀리는 꼴 2 1: continue를 break로 읽었습니다. continue는 그 바퀴만 건너뜁니다.
  • 틀리는 꼴 5 10: i가 2인 바퀴도 더했습니다. 9번 줄은 continue 아래라 실행되지 않습니다.

4. 자기를 뺀 약수를 모두 더한 값이 자기와 같은 수를 완전수(perfect number)라 합니다. 다음 코드의 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

#include <stdio.h>

int main(void) {
  int n = 8, d, s = 0;
  for (d = 1; d < n; d++)
    if (n % d == 0)
      s += d;
  if (s == n) {
    printf("완전수\n");
  } else {
    printf("%d\n", s);
  }
  return 0;
}
정답

받는 답:

실행 결과
7

d가 1부터 7까지 돌며 8을 나누어떨어지게 하는 1·2·4만 더해 s는 7입니다. 7은 8과 달라 else의 printf가 7을 찍습니다. 5번 줄 for와 6번 줄 if는 중괄호가 없어, for의 몸은 if 문장 하나이고 if의 몸은 7번 줄 한 문장입니다. n이 6이면 1 + 2 + 3이 6이라 완전수를 찍습니다.

  • 틀리는 꼴 15: d가 8일 때도 더했습니다. 조건이 d < n이라 8은 돌지 않습니다.
  • 틀리는 꼴 완전수: 6처럼 완전수일 것이라 짐작했습니다. 약수를 더해 보면 7입니다.

5. 다음 (가)~(다)에 들어갈 C 키워드를 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

  • (가) 반복 안에서 만나면 이번 바퀴의 남은 문장을 건너뛰고 다음 바퀴로 넘어가게 하는 문장
  • (나) 반복 안에서 만나면 반복을 그 자리에서 끝내고 반복 다음 줄로 가게 하는 문장
  • (다) 몸을 먼저 한 번 실행한 뒤 끝에서 조건을 보는 반복을 여는 첫 낱말
정답

받는 답: (가) continue · (나) break · (다) do

(가)는 '남은 문장만 건너뜀', (나)는 '반복 자체를 끝냄', (다)는 '조건을 끝에서 봄'이 실마리입니다.

  • 틀리는 꼴 break — (가)에: 반복 전체를 끝냅니다. 다음 바퀴가 없습니다.
  • 틀리는 꼴 while — (다)에: 조건을 먼저 보는 반복입니다. 끝에서 보는 반복은 do로 열고 while (조건);으로 닫습니다.

처음이라면: C 언어 과목(준비 중)의 'while과 추적 표' · 'for의 세 칸' · 'break와 continue' · 'do-while: 한 번은 실행' · '반복 안의 반복' 레슨에서 같은 규칙을 처음부터 천천히 봅니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

정보처리기사 목차로