이 페이지의 목차
알맞은 제어 구조 골라 쓰기
코드 예제: Python · C · 예상 50분
학습 목표
- 문제 상황에 알맞은 제어 구조를 선택하고 근거를 밝힌다.
- 제어 구조를 복합적으로 활용한 프로그램을 완성한다.
관련 성취기준
- 프그02-04
순차, 선택, 반복의 제어 구조를 이해하고, 문제 상황에 알맞은 제어 구조를 선택하여 이를 적용한 프로그램을 작성할 수 있다.
생각 열기 — 숫자 맞히기를 만들려면
1단원 6차시에서 숫자 맞히기 놀이를 했다. 그것을 프로그램으로 만들어야 한다.
정답은 정해져 있다. 사용자가 수를 넣으면 「더 큰 수」·「더 작은 수」·「정답」을 알려 준다. 기회는 다섯 번이다.
세 구조를 고르는 기준
| 문제의 모양 | 쓸 구조 | 판단 근거 |
|---|---|---|
| 정해진 일을 차례로 한 번 | 순차 | 갈라지지도 되풀이되지도 않는다 |
| 경우에 따라 다르게 | 선택 | 「~이면」 이라는 말이 요구 사항에 있다 |
| 횟수를 미리 안다 | 반복 — for | 「30명 전부」, 「9번」 처럼 개수가 정해져 있다 |
| 끝나는 조건만 안다 | 반복 — while | 「맞힐 때까지」, 「파일이 끝날 때까지」 |
| 표를 만든다 | 중첩 반복 | 행과 열, 두 방향으로 되풀이된다 |
| 걸러 내며 되풀이 | 반복 + 선택 | 「~인 것만」 이라는 말이 있다 |
for 와 while 가르기
가장 자주 헷갈리는 자리다. 기준은 하나다.
반복을 시작할 때 몇 번 돌지 아는가?
| 문제 | 아는가 | 고를 것 |
|---|---|---|
| 학생 30명의 점수를 더한다 | 안다 (30번) | for |
| 구구단 9단까지 찍는다 | 안다 (8 × 9) | for 중첩 |
| 정답을 맞힐 때까지 받는다 | 모른다 | while |
| 0을 넣을 때까지 값을 받는다 | 모른다 | while |
| 다섯 번 안에 맞히면 끝난다 | 최대 5번이지만 일찍 끝날 수 있다 | 둘 다 가능 |
마지막 줄이 숫자 맞히기다. 최대 횟수가 있으니 for 에 break 를 쓸 수도 있고, 남은 기회를 조건으로 두어 while 을 쓸 수도 있다.
정답 = 73
남은기회 = 5
while 남은기회 > 0:
추측 = int(input())
남은기회 -= 1
if 추측 == 정답:
print(추측, "정답")
break
elif 추측 < 정답:
print(추측, "더 큰 수")
else:
print(추측, "더 작은 수")
else:
print("기회를 다 썼다. 정답은", 정답)50 더 큰 수 90 더 작은 수 73 정답
#include <stdio.h>
int main(void)
{
int answer = 73;
int left = 5;
int guess;
int found = 0;
while (left > 0) {
if (scanf("%d", &guess) != 1) break;
left--;
if (guess == answer) {
printf("%d 정답\n", guess);
found = 1;
break;
} else if (guess < answer) {
printf("%d 더 큰 수\n", guess);
} else {
printf("%d 더 작은 수\n", guess);
}
}
if (!found) printf("기회를 다 썼다. 정답은 %d\n", answer);
return 0;
}50 90 73
50 더 큰 수 90 더 작은 수 73 정답
이 코드에 세 구조가 다 들어 있다
| 부분 | 구조 | 왜 그것인가 |
|---|---|---|
| 정답과 기회를 정하는 앞부분 | 순차 | 한 번만 하면 된다 |
while 남은기회 > 0 | 반복 (조건) | 몇 번 돌지 미리 모른다 — 일찍 맞힐 수 있다 |
if / elif / else | 선택 (다중) | 세 경우로 갈라진다 |
break | 반복 제어 | 맞혔으면 남은 기회를 쓸 필요가 없다 |
| 맨 아래 안내 | 선택 | 다 쓰고 못 맞힌 경우만 |
Python의 while / else
Python에는 반복에 else 를 붙일 수 있다. break 로 끊기지 않고 조건이 거짓이 되어 정상으로 끝났을 때만 실행된다. 그래서 “기회를 다 썼다”는 안내를 여기에 두면 딱 맞는다.
C에는 이 문법이 없다. 그래서 found 라는 표시 변수를 두고 반복 뒤에 검사한다.
읽기 쉽게 만드는 판단
같은 일을 하는 코드가 여러 가지일 때 무엇을 기준으로 고를까.
- 기준 1
중첩을 얕게
조건 안의 조건이 세 겹을 넘으면 조건을 합치거나 함수로 떼어 낸다.
- 기준 2
한 화면에 들어오게
반복 몸통이 화면을 넘어가면 안이 무슨 일을 하는지 안 보인다.
- 기준 3
끝나는 조건이 한눈에
while 을 쓸 때 무엇이 변해 끝나는지가 몸통 위쪽에서 보이게 둔다.
- 기준 4
이름으로 설명
조건이 길면 남은기회·정답맞음 처럼 이름을 붙여 뜻을 드러낸다.
활동
숫자 맞히기 게임 만들기
약 30분1단계 — 입력을 바꿔 실행한다 (5분)
「입력」 칸의 값을 바꿔 각 경우를 확인한다.
| 넣은 값 | 예상 결과 | 실제 결과 |
|---|---|---|
73 (한 번에 맞힘) |
||
50 60 70 72 73 (다섯 번째에 맞힘) |
||
1 2 3 4 5 (다 틀림) |
||
100 90 80 75 74 (다 틀림) |
세 번째와 네 번째에서 맨 아래 안내가 나오는지 확인한다.
2단계 — 구조를 표로 분해한다 (5분)
코드의 각 부분이 어느 구조인지 적는다. 본문의 표를 보지 않고 먼저 해 본다.
| 코드 부분 | 구조 | 왜 |
|---|---|---|
3단계 — for 로 바꿔 본다 (10분)
while 대신 for 로 같은 프로그램을 만들어 본다.
- 다섯 번 도는
for를 쓰고 맞히면break한다. - Python에서는
for / else도 쓸 수 있다.while / else와 같은 방식이다. - 두 코드를 나란히 놓고 견줘 본다.
while 판 |
for 판 |
|
|---|---|---|
| 남은 기회를 어떻게 아는가 | ||
| 끝나는 조건이 어디에 적혀 있는가 | ||
| 어느 쪽이 읽기 쉬운가 (근거와 함께) |
4단계 — 기능을 하나 더한다 (10분)
요구 사항을 늘려 보자.
사용자가
0을 넣으면 포기한 것으로 보고 정답을 알려 주며 끝낸다. 범위(1~100) 밖의 값을 넣으면 기회를 쓰지 않고 다시 받는다.
- 「0을 넣으면」은 어느 구조인가? 어디에 넣어야 하는가?
- 「기회를 쓰지 않고 다시 받는다」는 무엇을 쓰면 되는가? (10차시의 반복 제어)
- 기회를 줄이는 줄의 자리를 옮겨야 하는가? 왜?
다 만들면 3단원 7차시처럼 테스트 사례를 적어 확인한다.
| 넣을 값 | 기대 결과 |
|---|---|
0 |
|
200 73 |
|
-5 73 |
개념 확인 문제
보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.
「정답을 맞힐 때까지 값을 받는다」는 요구 사항에 알맞은 반복은?프그02-04
Python의 while / else 에서 else 가 실행되는 경우는?프그02-04
C 코드에서 found 변수를 둔 까닭은?프그02-04
요구 사항에 「90점 이상인 학생만 세어라」 라고 적혀 있다. 필요한 구조는?프그02-04
같은 일을 하는 코드 중 무엇을 고를지 판단하는 기준으로 알맞지 않은 것은?프그02-04
「범위 밖의 값을 넣으면 기회를 쓰지 않고 다시 받는다」를 구현할 때 쓰는 것은?프그02-04
더 알아보기
심화적어도 한 번은 실행해야 할 때
while 은 조건을 먼저 검사하므로 처음부터 거짓이면 한 번도 안 돈다. 그런데 “일단 한 번은 물어보고, 계속할지 그다음에 정한다” 같은 경우가 있다. 메뉴를 보여 주고 선택을 받는 프로그램이 그렇다.
C에는 이런 경우를 위한 do / while 이 있다. 몸통을 먼저 실행하고 조건을 나중에 검사한다.
do {
메뉴를 보여 준다
선택을 받는다
} while (선택 != 0);Python에는 이 문법이 없어 while True: 로 돌리고 안에서 break 로 빠져나가는 얼개를 쓴다. 문법이 없으면 얼개로 만든다는 이야기가 여기서도 통한다.
실무세 구조로 못 하는 일은 없다
순차·선택·반복 세 가지만으로 어떤 계산이든 표현할 수 있다는 것이 알려져 있다. 프로그램의 흐름을 이 셋으로 짜는 방식을 구조적 프로그래밍이라 하고, 오늘날 대부분의 언어가 이 셋을 기본으로 갖추고 있다.
옛 언어에는 코드의 아무 줄로나 건너뛰는 문법이 있었다. 짧게 적을 수 있었지만, 흐름이 실타래처럼 엉켜 읽을 수 없는 코드가 되기 쉬웠다. 그래서 지금은 거의 쓰지 않는다. 읽을 수 있게 만드는 것이 짧게 만드는 것보다 중요하다는 판단이 언어 설계 차원에서 내려진 셈이다.
심화무작위 수로 정답을 정하려면
지금 코드는 정답이 73 으로 고정되어 있다. 실제 게임이라면 매번 달라야 한다. Python에서는 import random 뒤에 random.randint(1, 100) 을 쓴다.
이 교과서의 예제가 정답을 고정한 데는 이유가 있다. 실행할 때마다 결과가 달라지면 기대 출력과 대조할 수 없기 때문이다. 3단원 7차시에서 테스트는 미리 정한 결과와 대조하는 일이라고 했다. 무작위가 들어간 프로그램을 테스트할 때는 무작위 부분을 떼어 내고 값을 넘겨받는 형태로 만든다 — 16차시에서 함수로 나누는 것을 배우면 이 방법을 쓸 수 있다.
이어지는 학습
이 차시를 이해하려면 다음을 먼저 알아야 한다.
- 11차시의 중첩 제어 구조 — 프로그래밍 프그02-04
교과서에서 찾기
| 교과서 | 해당 위치 | 쪽수 |
|---|---|---|
| 성림출판(Python) | 프로그래밍의 기초 › 04 제어문 | 126쪽 |
| 씨마스커뮤니케이션(Python) | 프로그래밍 기초 › 4 제어문 | 120쪽 |
| 삼양미디어(Python) | 프로그래밍의 기초 › 03 제어 구조 | 98쪽 |
| 삼양미디어(C) | 프로그래밍의 기초 › 03 제어 구조 | 100쪽 |
| 씨마스(C) | C 프로그래밍의 기초 › 4 제어문 | 96쪽 |
| 웅보출판사(C) | 프로그래밍의 기초 › Chapter 04 제어문 | 116쪽 |