이 페이지의 목차
반복 — 같은 일을 여러 번
코드 예제: Python · C · 예상 50분
학습 목표
- 반복 구조의 종류와 동작 방식을 설명한다.
- 반복 횟수가 정해진 경우와 조건에 따라 끝나는 경우를 구분해 작성한다.
관련 성취기준
- 프그02-04
순차, 선택, 반복의 제어 구조를 이해하고, 문제 상황에 알맞은 제어 구조를 선택하여 이를 적용한 프로그램을 작성할 수 있다.
생각 열기 — 1부터 100까지 더하기
1부터 100까지 더한 값을 구해야 한다. 지금까지 배운 것으로 하면 이렇게 된다.
합계 = 1 + 2 + 3 + 4 + 5 + ...
100개를 손으로 적어야 한다. 1000까지라면 1000개다.
반복 구조 — 되돌아가는 흐름
반복 구조(iteration) — 조건을 만족하는 동안 같은 부분을 되풀이해 실행하는 흐름는 1단원 7차시 순서도에서 위로 되돌아가는 화살표로 그렸던 그것이다.
되풀이를 멈추는 방식에 따라 두 갈래로 나눈다.
- 횟수 반복
몇 번 할지 정해져 있다
구구단 9번, 학생 30명. 시작·끝·간격을 미리 안다. for 문을 쓴다.
- 조건 반복
조건이 거짓이 될 때까지
맞힐 때까지, 파일이 끝날 때까지. 몇 번 돌지 미리 모른다. while 문을 쓴다.
단 = 3
for i in range(1, 10):
print(f"{단} x {i} = {단 * i}")
합계 = 0
n = 1
while n <= 100:
합계 += n
n += 1
print("1부터 100까지의 합:", 합계)3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 3 x 4 = 12 3 x 5 = 15 3 x 6 = 18 3 x 7 = 21 3 x 8 = 24 3 x 9 = 27 1부터 100까지의 합: 5050
#include <stdio.h>
int main(void)
{
int dan = 3;
for (int i = 1; i <= 9; i++)
printf("%d x %d = %d\n", dan, i, dan * i);
int sum = 0, n = 1;
while (n <= 100) {
sum += n;
n++;
}
printf("1부터 100까지의 합: %d\n", sum);
return 0;
}3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 3 x 4 = 12 3 x 5 = 15 3 x 6 = 18 3 x 7 = 21 3 x 8 = 24 3 x 9 = 27 1부터 100까지의 합: 5050
range(1, 10) 이 9번인 까닭
3차시의 슬라이싱과 같은 규칙이다.
시작은 포함하고 끝은 포함하지 않는다.
range(1, 10) 은 1, 2, …, 9 로 아홉 개다. 10은 들어가지 않는다. 그래서 개수는 끝 − 시작 으로 바로 나온다.
| 하려는 일 | Python | C |
|---|---|---|
| 1부터 9까지 | range(1, 10) | for (i = 1; i <= 9; i++) |
| 0부터 4까지 | range(5) | for (i = 0; i < 5; i++) |
| 2씩 뛰며 0~8 | range(0, 10, 2) | for (i = 0; i < 10; i += 2) |
| 거꾸로 9→1 | range(9, 0, -1) | for (i = 9; i >= 1; i--) |
| 리스트를 훑기 | for x in 점수: | for (i = 0; i < n; i++) 로 번호를 돌린다 |
for 문의 세 부분 (C)
C의 for (int i = 1; i <= 9; i++) 는 세 조각으로 되어 있다.
for ( int i = 1 ; i <= 9 ; i++ )
└─ 처음에 ─┘ └ 언제까지 ┘ └ 한 번 돌 때마다 ┘
한 번만 실행 거짓이 되면 끝 몸통 뒤에 실행
세 조각이 1단원 7차시 순서도의 준비·판단·처리에 그대로 대응한다.
| 순서도 | C의 for |
|---|---|
준비 (i ← 1) |
첫째 조각 |
판단 (i ≤ 9 ?) |
둘째 조각 |
되돌아가기 전 처리 (i ← i + 1) |
셋째 조각 |
무한 루프 — 끝나지 않는 반복
1단원 6차시의 유한성이 여기서 실제 문제가 된다. 반복을 끝내는 것이 무엇인지 늘 확인해야 한다.
n = 1
while n <= 100:
합계 += n
# n += 1 을 빠뜨리면?
n 이 늘지 않으므로 n <= 100 이 언제나 참이다. 끝나지 않는다.
반복을 적을 때마다 스스로 물어야 할 것은 하나다.
무엇이 변해서 이 반복이 끝나는가?
for 문은 셋째 조각이 그 답을 강제로 적게 만든다. 그래서 횟수가 정해진 일에는 for 가 안전하다. while 은 그 답을 몸통 안에 사람이 적어야 하므로 빠뜨릴 수 있다.
반복을 도중에 끊고 건너뛰기
| 하려는 일 | Python | C | 언제 쓰나 |
|---|---|---|---|
| 반복 자체를 끝낸다 | break | break | 찾던 것을 찾았을 때 |
| 이번 회차만 건너뛴다 | continue | continue | 이 값은 처리하지 않을 때 |
3단원 6차시의 summarize 에서 범위 밖 값을 만났을 때 continue 를 쓴 것이 그 예다. 12차시의 숫자 맞히기에서는 정답을 맞혔을 때 break 로 끝낸다.
활동
구구단 표 출력과 합계 구하기
약 25분1단계 — 단을 바꿔 본다 (5분)
실행기의 [고치기]로 단 값을 바꿔 2단부터 9단까지 확인한다.
- 코드에서 고친 곳이 몇 군데인가?
- 이것을
for하나 더로 자동화하려면 어떻게 할까? (11차시에서 다룬다)
2단계 — range 를 바꿔 본다 (10분)
range 를 바꿔 가며 표를 채운다. 먼저 예상을 적는다.
| range | 예상 (몇 번, 어떤 값) | 실제 |
|---|---|---|
range(1, 10) |
9번, 1~9 | |
range(10) |
||
range(1, 10, 2) |
||
range(9, 0, -1) |
||
range(1, 1) |
||
range(10, 1) |
마지막 두 줄에서 한 번도 안 도는 경우를 확인한다. 그런 일이 왜 생기는가?
3단계 — 무한 루프를 겪어 본다 (5분)
while 문에서 n += 1 을 지우고 실행한다.
| 확인할 것 | 결과 |
|---|---|
| 몇 초 뒤에 멈췄나 | |
| 어떤 안내가 나왔나 | |
| 그 동안 페이지의 다른 곳을 누를 수 있었나 | |
| [■ 중단] 을 누르면 바로 멈추나 |
되돌려 놓는다.
4단계 — while 을 for 로 바꿔 본다 (5분)
1부터 100까지의 합을 while 대신 for 로 적어 본다.
- 어느 쪽이 짧은가?
- 어느 쪽이 반복이 끝나는 조건을 빠뜨리기 어려운가? 왜 그런가?
- 합이 5050이 맞는지 확인한다. (1부터 n까지의 합은
n × (n+1) ÷ 2다)
개념 확인 문제
보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.
range(1, 10) 은 몇 번 도는가?프그02-04
횟수가 정해진 반복에 for 를 쓰는 것이 더 안전한 까닭은?프그02-04
while n <= 100: 안에서 n += 1 을 빠뜨리면?프그02-04
C의 for (int i = 1; i <= 9; i++) 에서 i++ 는 언제 실행되는가?프그02-04
break 와 continue 의 차이는?프그02-04
range(10, 1) 은 어떻게 동작하는가?프그02-04
더 알아보기
심화1부터 100까지를 반복 없이 구하기
n × (n+1) ÷ 2 라는 식으로 한 번에 구할 수 있다. 100 × 101 ÷ 2 = 5050이다. 반복은 100번 도는데 이 식은 계산 세 번이면 끝난다. 1단원 6차시에서 다룬 효율의 차이다.
여기서 배울 것은 “공식을 외우자”가 아니다. 되풀이하는 일에 규칙이 있으면 더 짧은 길이 있을 수 있다는 점이다. 다만 규칙을 찾기 어렵거나 값이 몇 개뿐이라면 반복이 읽기 쉽고 고치기도 쉽다. 어느 쪽을 택할지는 3차시에서 배운 대로 상황이 정한다.
심화반복 변수의 수명
C의 for (int i = 1; ...) 에서 i 는 그 반복 안에서만 산다. 반복이 끝나면 사라져 바깥에서 쓸 수 없다. 반복 밖에서도 i 값을 봐야 하면 for 앞에서 선언해야 한다.
Python의 for i in range(...) 는 다르다. 반복이 끝난 뒤에도 i 가 마지막 값을 담은 채 남아 있다. 편할 때도 있지만, 반복 안에서 쓰던 이름이 바깥으로 새어 나와 나중에 헷갈리는 원인이 되기도 한다. 15차시에서 변수의 유효 범위를 다룰 때 이 이야기를 이어 간다.
실무한 칸 차이로 생기는 잘못
반복 횟수를 한 번 더 돌거나 한 번 덜 도는 실수가 아주 흔하다. i <= n 과 i < n 을 잘못 고르는 것이 대표적이다. 4차시에서 배열 범위를 넘어가면 C가 조용히 옆 메모리를 읽는다고 했는데, 그 원인 대부분이 이 한 칸 차이다.
막는 방법은 하나뿐이다 — 경계에서 확인하는 것. 반복이 도는 첫 회차와 마지막 회차에 어떤 값이 들어가는지 손으로 적어 본다(3단원 4차시의 책상 검사). 목록 크기가 0일 때 한 번도 안 도는지도 함께 본다. 위 활동 2단계에서 range(1, 1) 을 넣어 본 것이 그 연습이다.
이어지는 학습
이 차시를 이해하려면 다음을 먼저 알아야 한다.
- 9차시의 선택 구조 — 프로그래밍 프그02-04
교과서에서 찾기
| 교과서 | 해당 위치 | 쪽수 |
|---|---|---|
| 성림출판(Python) | 프로그래밍의 기초 › 04 제어문 | 126쪽 |
| 씨마스커뮤니케이션(Python) | 프로그래밍 기초 › 4 제어문 | 120쪽 |
| 삼양미디어(Python) | 프로그래밍의 기초 › 03 제어 구조 | 98쪽 |
| 삼양미디어(C) | 프로그래밍의 기초 › 03 제어 구조 | 100쪽 |
| 씨마스(C) | C 프로그래밍의 기초 › 4 제어문 | 96쪽 |
| 웅보출판사(C) | 프로그래밍의 기초 › Chapter 04 제어문 | 116쪽 |