본문 바로가기
Topos Uranos

요약

문제에서 알고리즘으로 수업은 단계를 조합하는 세 가지 방식, 곧 순차, 선택, 반복을 구별했다. 앞의 두 방식은 이미 C++에서 쓰는 법이 있으며, 이 수업은 세 번째 방식에 그 쓰는 법을 준다. 반복문의 세 가지 형태를 공부한다. 매 회차 전에 조건을 계산하며 본문을 한 번도 실행하지 않을 수도 있는 while 문, 조건을 나중에 계산하며 본문을 적어도 한 번은 실행하는 do 문, 그리고 반복을 지배하는 변수의 초기화, 조건, 증감을 한 줄에 모으는 for 문이다. 세 형태가 같은 메커니즘을 표현하므로 각 형태를 나머지 형태로 바꿀 수 있음을 보이고, 가장 명료한 형태를 고르는 법을 가르친다. 회차의 진행을 바꾸는 break 문과 continue 문을 소개하고, 끝으로 중첩 반복문을 다룬다. 중첩 반복문에서 안쪽 본문이 실행되는 횟수는 합으로 계산된다. 수업 전체에 함께하는 도구는 추적표이다. 반복문을 손으로, 한 회차씩 따라가는 것이 본문이 몇 번 실행되는지, 그리고 빠져나올 때 무엇을 남기는지 예측하는 방법이다.

학습 목표

  1. 주어진 반복에 대해 가장 명료한 형태를 골라 while, do, for 반복문을 쓴다.
  2. 반복문을 추적표로 손으로 따라가고 본문이 몇 번 실행되는지 예측한다.
  3. 반복문을 의미를 보존하면서 한 형태에서 다른 형태로 바꾼다.
  4. 중첩 반복문을 쓰고 안쪽 본문이 몇 번 실행되는지 계산한다.

while

while 문의 형태

while 문은 이렇게 쓴다.

C++ 코드
while (조건) {    본문}

그 의미는 세 단계로 기술된다. 조건을 계산한다. 거짓이면 반복문이 끝나고 실행은 반복문을 닫는 중괄호 뒤로 이어진다. 참이면 본문을 실행하고 첫 단계로 돌아간다. 본문의 각 실행을 회차(또는 반복)라고 한다. 조건은 관계와 논리 수업에서 다룬 것과 같은 불리언 식이고, 본문은 블록이다. 조건문 수업이 정한 중괄호 규칙은 여기에도 적용된다. 반복문의 본문은 문이 하나뿐이어도 언제나 중괄호로 감싼다.

정의로부터 두 가지 귀결이 나온다. 첫째, 조건은 매 회차 전에 계산되므로, 처음부터 거짓이면 본문은 한 번도 실행되지 않는다. 둘째, 반복문이 끝나려면 본문은 조건이 읽는 것 가운데 무언가를 바꾸어야 한다. 아무것도 바뀌지 않으면 한 번 참이었던 조건은 언제까지나 참이다. 그러나 바꾸는 것만으로는 충분하지 않다. 문제에서 알고리즘으로 수업은 매 회차 줄어드는 자연수 양, 곧 변량이 필요함을 보였고, 올바른 반복문 설계 수업은 그것을 하나의 방법으로 만들 것이다.

뺄셈을 거듭하는 나눗셈

이 강좌에서 반복을 포함한 첫 알고리즘은 뺄셈을 거듭하는 나눗셈이었다. 나머지가 나누는 수 이상인 동안 나머지에서 나누는 수를 빼고 몫에 1을 더한다. C++로 쓰면 이 알고리즘은 거의 한 단어 한 단어 그대로 옮겨진다.

예시뺄셈으로 구하는 몫과 나머지
C++ 프로그램
#include <iostream>#include <print>​int main(){    int a{};    int b{};    std::cin >> a >> b;    int q{0};    int r{a};    while (r >= b) {        r -= b;        ++q;    }    std::println("{} = {} · {} + {}", a, b, q, r);}
프로그램 입력
23 7
출력
23 = 7 · 3 + 2

9행과 10행은 변수에 초깃값을 준다. 아직 아무것도 빼지 않았으므로 몫은 0이고 나머지는 피제수 전체이다. 11행은 알고리즘의 2단계 조건이고, 12행과 13행이 본문이다. 프로그램은 알고리즘과 마찬가지로 a≥0a \geq 0 및 b>0b > 0 조건을 가정한다. b=0b = 0일 때는 12행이 r 변수를 바꾸지 않아 반복문이 끝나지 않을 것이다.

추적표

반복문을 손으로 따라가는 것은 표를 채우는 일이다. 회차마다 한 행, 변수마다 한 열, 그리고 회차가 시작될 때 계산한 조건을 위한 한 열을 둔다. 0행에는 첫 계산 전의 상태를 적고, 마지막 행에는 거짓이 되어 반복문을 끝내는 계산을 적는다.

예시23 나누기 7의 추적

증명

  1. 반복문 전에 9행과 10행이 실행된다. q=0q = 0, r=23r = 23 상태가 된다. 이것이 0행이며, 조건은 아직 계산되지 않았다.

  2. 1회차. 조건 23≥723 \geq 7의 값이 참이므로 본문이 실행된다. rr의 값은 16이 되고 qq의 값은 1이 된다. 그 뒤 실행은 11행으로 돌아간다.

  3. 2회차. 16≥716 \geq 7의 값이 참이다. rr의 값은 9가 되고 qq의 값은 2가 된다.

  4. 3회차. 9≥79 \geq 7의 값이 참이다. rr의 값은 2가 되고 qq의 값은 3이 된다.

  5. 네 번째 계산 2≥72 \geq 7의 값은 거짓이다. 본문은 실행되지 않고, 반복문이 끝나며, 15행이 23=7⋅3+223 = 7 \cdot 3 + 2 식을 출력한다.

추적은 세는 법을 가르쳐 준다. 본문은 몫과 같은 세 번 실행되었고, 조건은 네 번 계산되었다. 회차마다 한 번, 그리고 실패하는 한 번이 더 있다. 이 관계는 조건으로 끝나는 모든 while 문에 성립한다. 본문이 kk번 실행되면 조건은 k+1k + 1번 계산된다. 극단적인 경우도 이를 확인해 준다. 입력이 5 7 값일 때 첫 계산 5≥75 \geq 7의 값이 이미 거짓이어서 본문은 0번 실행되고, 프로그램은 5=7⋅0+55 = 7 \cdot 0 + 5 식을 출력하는데, 이는 옳다. 잘 쓴 while 문은 반복할 것이 없는 경우를 별도의 코드 없이 처리한다.