본문 바로가기

while과 do-while 반복문

while과 do-while의 조건 검사 시점을 비교하고 횟수를 모르는 반복과 입력 검증 흐름을 안전하게 작성합니다.

때로는 반복 횟수를 미리 알 수 없거나, 특정 조건이 만족될 때까지 계속 반복해야 하는 경우가 있습니다.

예를 들어 사용자가 올바른 값을 입력할 때까지 계속 입력받거나, 파일의 끝에 도달할 때까지 데이터를 읽는 것과 같은 상황이 있을 수 있습니다.

이런 경우에 적합한 반복문이 바로 while 문과 do-while 문입니다.

이 장에서는 이 두 반복문의 특징과 사용법을 다룹니다.

먼저 while과 do-while을 조건을 검사하는 시점이 다른 반복문으로 나눠 봅니다.

C++ while 문은 매 반복의 본문보다 먼저 조건을 검사해 본문을 0번 실행할 수 있고, do-while 문은 본문을 먼저 실행한 뒤 조건을 검사해 최소 한 번 실행한다는 제어 흐름 비교

PRE-TEST · POST-TEST

while은 먼저 검사하고 do-while은 먼저 실행한다

둘 다 검사 결과가 true이면 반복하고 false이면 빠져나옵니다. 갈리는 지점은 첫 검사보다 본문이 앞에 있는지입니다.

선검사와 후검사의 첫 경로와 반복 경로 비교두 독립 반복을 각각 네 노드와 네 간선으로 비교한다. while은 진입 뒤 조건을 먼저 검사하고 참이면 본문을 실행한 뒤 조건으로 돌아간다. 처음 거짓이면 본문0회다. do-while은 진입 뒤 본문을 먼저 실행하고 조건을 검사하며 참이면 본문으로 돌아간다. 따라서 정상 진입 시 본문을 최소1회 실행한다. 두 그림은 한 프로그램에서 서로 이어지는 실행 순서가 아니다.while · 선검사진입첫 검사부터 시작조건?본문 전 검사본문 · 상태 갱신처음 false면0회반복 다음false면 종료true재검사falsedo-while · 후검사진입첫 조건 검사 없음본문 · 상태 갱신최소1회 실행조건?본문 뒤 검사반복 다음false면 종료truefalse
선검사와 후검사의 첫 경로와 반복 경로 비교두 독립 반복을 각각 네 노드와 네 간선으로 비교한다. while은 진입 뒤 조건을 먼저 검사하고 참이면 본문을 실행한 뒤 조건으로 돌아간다. 처음 거짓이면 본문0회다. do-while은 진입 뒤 본문을 먼저 실행하고 조건을 검사하며 참이면 본문으로 돌아간다. 따라서 정상 진입 시 본문을 최소1회 실행한다. 두 그림은 한 프로그램에서 서로 이어지는 실행 순서가 아니다.while · 선검사진입첫 검사부터 시작조건?본문 전 검사본문 · 상태 갱신처음 false면0회반복 다음false면 종료true재검사falsedo-while · 후검사진입첫 조건 검사 없음본문 · 상태 갱신최소1회 실행조건?본문 뒤 검사반복 다음false면 종료truefalse

while (조건) { 본문 }

본문 전에 검사하는 선검사 반복

  1. 조건 검사

    조건 값을 bool로 문맥 변환합니다. 처음부터 false면 본문을 건너뜁니다.

  2. true일 때 본문 실행

    본문의 끝에 도달하면 다음 조건 검사로 되돌아갑니다.

  3. false면 종료

    while 다음 문장으로 제어가 이어집니다.

최소 실행 횟수: 0회

do { 본문 } while (식);

본문 뒤에 검사하는 후검사 반복

  1. 본문 먼저 실행

    진입할 때는 검사하지 않으므로 본문이 반드시 한 번 실행됩니다.

  2. 식 검사

    본문 실행 뒤 식을 bool로 문맥 변환합니다.

  3. true면 반복, false면 종료

    반복하면 다시 본문부터 실행하고, 끝나면 다음 문장으로 이어집니다.

최소 실행 횟수: 1회

continue는 가장 안쪽 반복문의 계속 지점으로 이동합니다. while은 앞의 조건 검사, do-while은 본문 뒤의 식 검사입니다. break는 가장 안쪽 반복문 또는 switch 하나를 끝냅니다.

while 문: 조건이 참인 동안 반복

while 문은 주어진 조건이 참(true)인 동안 코드 블록을 반복적으로 실행합니다.

for 문과 달리 초기화와 상태 갱신을 조건식과 별도로 작성하므로, 반복 횟수보다는 조건에 중점을 둔 반복에 더 적합합니다.

while 문 형식
// (초기화는 보통 while 문 바깥에서 수행)
while (조건) {
    // 조건이 true인 동안 반복적으로 실행할 코드
    // 조건이 끝나도록 상태를 바꾸거나 명시적인 탈출 경로를 둠
}
  • 조건: 매 반복이 시작되기 전에 평가됩니다. 이 조건이 true이면 반복 몸체가 실행되고, false이면 while 문이 종료됩니다.
  • { } (중괄호): 조건이 참일 때 실행될 코드 블록입니다.
  • while 문은 for 문과 달리 초기화와 증감 부분이 문법에 따로 포함되어 있지 않습니다. 끝나야 하는 반복이라면 조건이 언젠가 false가 되도록 상태를 갱신하거나, 도달 가능한 break·return 같은 탈출 경로를 두어야 합니다.
while 문의 실행 흐름

조건 부분이 평가됩니다.

만약 조건이 true이면, while 문의 반복 몸체({ } 안의 코드)가 실행됩니다.

반복 몸체 실행이 끝나면, 다시 1번 단계로 돌아가 조건 부분을 평가합니다.

조건이 false가 될 때까지 2, 3번 과정을 반복합니다.

조건이 false가 되면 while 문이 종료되고 다음 코드가 실행됩니다.

예시 1: 1부터 5까지 출력하기 (while 문)
#include <iostream>

int main() {
    int i = 1; // 초기화

    while (i <= 5) { // 조건
        std::cout << i << " ";
        i++; // 증감
    }
    std::cout << std::endl; // 출력: 1 2 3 4 5

    return 0;
}
예시 2: 사용자로부터 올바른 나이 입력받기 (while 문)
#include <iostream>
#include <limits>

int main() {
    int age;
    std::cout << "나이를 입력하세요 (1-120): ";

    // 정수 추출에 성공하고 값이 유효한 범위에 들어올 때까지 반복
    while (!(std::cin >> age) || age < 1 || age > 120) {
        if (std::cin.eof()) {
            std::cerr << "입력이 종료되었습니다." << std::endl;
            return 1;
        }

        // 비정수 입력으로 설정된 오류 상태를 풀고 현재 입력 줄을 버림
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "잘못된 나이입니다. 1에서 120 사이의 숫자를 다시 입력하세요: ";
    }

    std::cout << "입력하신 나이: " << age << std::endl; // 출력: 입력하신 나이: (사용자가 입력한 유효한 나이)

    return 0;
}

while (true)의 조건 자체는 항상 참이므로 조건 검사만으로는 루프가 끝나지 않습니다.

이 경우, break 문을 사용하여 특정 조건이 만족되면 루프를 강제로 종료할 수 있습니다.

이 명령 예제는 입력이 계속 성공하고 마지막에 exit을 입력하는 상황에서 break를 보여 줍니다. 입력 종료나 스트림 실패를 검사하지 않으므로 실제 입력 도구의 완성형으로 사용하지 않습니다. 아래 안전한 읽기 예제에서는 추출 실패 자체도 종료 조건으로 둡니다.

예시 3: 무한 루프와 break 문
#include <iostream>
#include <string>

int main() {
    std::string command;
    std::cout << "명령을 입력하세요 ('exit'을 입력하면 종료):" << std::endl;

    while (true) { // 무한 루프
        std::cout << "> ";
        std::cin >> command;

        if (command == "hello") {
            std::cout << "안녕하세요!" << std::endl;
        } else if (command == "exit") {
            std::cout << "프로그램을 종료합니다." << std::endl;
            break; // 'exit'이 입력되면 루프 탈출
        } else {
            std::cout << "알 수 없는 명령입니다." << std::endl;
        }
    }

    return 0;
}

do-while 문: 최소 한 번은 실행되는 반복

do-while 문은 while 문과 유사하지만, 조건을 반복 몸체 실행 후에 평가한다는 점에서 차이가 있습니다.

이로 인해 do-while 문의 반복 몸체는 조건의 참/거짓 여부와 관계없이 최소 한 번은 반드시 실행됩니다.

do-while 문 형식
do {
    // 최소 한 번은 실행될 코드
    // 끝나야 하는 반복이라면 상태 갱신 또는 명시적인 탈출 경로를 둠
} while (조건); // 조건 뒤에 세미콜론(;) 필수!
  • do 블록 안의 코드가 먼저 실행됩니다.
  • 그 후에 while 괄호 안의 조건이 평가됩니다.
  • 조건이 true이면 do 블록으로 돌아가 다시 실행하고, false이면 반복문이 종료됩니다.
  • while (조건); 뒤에 반드시 세미콜론(;)을 붙여야 합니다.
do-while 문의 실행 흐름

do 블록의 반복 몸체({ } 안의 코드)가 실행됩니다.

조건 부분이 평가됩니다.

만약 조건이 true이면, 1번 단계로 돌아가 반복 몸체를 다시 실행합니다.

조건이 false가 되면 do-while 문이 종료되고 다음 코드가 실행됩니다.

예시 1: 사용자로부터 최소 한 번은 입력받기
#include <iostream>
#include <limits>

int main() {
    int num;
    bool valid = false;

    // do-while은 최소 한 번은 실행되므로, 첫 입력 유도 메시지를 루프 안에 넣기 편리
    do {
        std::cout << "0에서 9 사이의 숫자를 입력하세요: ";

        if (std::cin >> num) {
            valid = (num >= 0 && num <= 9);
        } else {
            if (std::cin.eof()) {
                std::cerr << "입력이 종료되었습니다." << std::endl;
                return 1;
            }
            std::cin.clear();
            valid = false;
        }

        // 성공 여부와 관계없이 현재 입력 줄의 나머지를 버림
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    } while (!valid); // 정수 추출에 성공하고 값이 유효할 때까지 반복

    std::cout << "입력하신 숫자: " << num << std::endl;

    return 0;
}

만약 사용자가 첫 입력으로 5를 입력하면 valid가 true가 되고, 반복 조건 !valid가 false로 평가되어 루프가 종료됩니다.

나이 예제와 이 숫자 예제는 정수 추출과 값의 범위를 검사합니다. 줄 전체의 형식 검사는 아닙니다. 예를 들어 일반적인 십진 입력 5abc에서는 앞의 5를 읽는 데 성공하며, 여기서는 ignore가 나머지 abc를 버립니다. 나이 예제의 성공 경로는 줄의 나머지를 버리지도 않습니다. “추출 성공”, “값이 범위 안”, “줄 전체에 추가 문자가 없음”은 서로 다른 요구입니다.

사용자가 첫 입력으로 10을 입력하면 valid가 false이므로 !valid가 true로 평가되어 다시 입력을 요청하게 됩니다.

아래 메뉴도 정수 입력이 성공하며 마지막에 3을 선택한다고 가정합니다. choice를 읽은 뒤 성공 여부를 검사하지 않으므로 입력 실패 복구 예제가 아닙니다. 입력 실패를 다루는 프로그램에서는 값으로 분기하기 전에 추출 결과부터 검사합니다.

예시 2: 메뉴 선택 (do-while 활용)
#include <iostream>

int main() {
    int choice;
    do {
        std::cout << "\n--- 메뉴 ---" << std::endl;
        std::cout << "1. 게임 시작" << std::endl;
        std::cout << "2. 설정" << std::endl;
        std::cout << "3. 종료" << std::endl;
        std::cout << "선택: ";
        std::cin >> choice;

        switch (choice) {
            case 1:
                std::cout << "게임을 시작합니다!" << std::endl;
                break;
            case 2:
                std::cout << "설정 화면으로 이동합니다." << std::endl;
                break;
            case 3:
                std::cout << "게임을 종료합니다. 안녕히 가세요!" << std::endl;
                break;
            default:
                std::cout << "잘못된 선택입니다. 다시 입력해주세요." << std::endl;
                break;
        }

    } while (choice != 3); // choice가 3이 아니면 계속 반복

    return 0;
}

이 예시에서 메뉴는 최소 한 번은 출력되고 사용자의 입력을 받습니다.

사용자가 3을 입력하기 전까지 계속 메뉴가 반복됩니다.


for vs while vs do-while 비교

반복문을 고를 때는 반복 횟수가 정해져 있는지, 조건을 실행 전에 검사해야 하는지, 본문을 최소 한 번 실행해야 하는지를 먼저 가르면 됩니다.

특징for 문while 문do-while 문
초기화, 조건, 증감한 줄에 명시적으로 표현초기화는 외부, 증감은 내부에서 수동 관리초기화는 외부, 증감은 내부에서 수동 관리
반복 실행 조건루프 시작 전 조건 검사루프 시작 전 조건 검사루프 실행 후 조건 검사
최소 실행 횟수0번 (조건이 처음부터 false이면)0번 (조건이 처음부터 false이면)1번 (조건과 관계없이)
적합한 상황반복 횟수가 명확할 때 (예: 배열 순회), 규칙적인 증감이 필요할 때조건이 만족될 때까지 반복할 때 (예: 파일 읽기, 사용자 입력)최소 한 번은 실행해야 할 때 (예: 메뉴 시스템, 유효성 검사)
주의사항끝나야 한다면 조건·반복식·탈출 경로 확인끝나야 한다면 상태 갱신 또는 도달 가능한 탈출 경로 확인while 뒤에 세미콜론(;) 필수, 상태 갱신 또는 도달 가능한 탈출 경로 확인

무한 루프 (Infinite Loops)

반복문의 조건이 항상 true로 평가되도록 작성되면 무한 루프(Infinite Loop)가 됩니다.

이는 프로그램이 끝나지 않고 계속 실행되는 상태를 만듭니다.

의도적인 경우가 아니면 버그로 이어집니다.

일반적인 무한 루프의 원인
  • while 문에서 조건을 변화시키는 코드가 없거나 잘못된 경우.
  • for 문에서 조건이 항상 true인 경우 (예: for (;;)).
무한 루프 예시
int counter = 0;
while (counter < 5) { // counter는 항상 0이므로 조건이 항상 true
    std::cout << "반복 중..." << std::endl;
    // counter++;  // 이 증감 코드가 없어서 무한 루프!
}

조건으로 끝내지 않는 반복은 while (true)나 for (;;)처럼 의도를 드러낼 수 있습니다. 내부에서 끝나야 하는 작업이라면 도달 가능한 break나 return 같은 별도 종료 경로가 필요하고, 계속 실행하도록 설계한 작업이라면 외부 중단 방식과 수명을 함께 정해야 합니다.

무한 루프는 조건식 자체보다 조건을 바꾸는 코드가 실제로 실행되는지에서 자주 갈립니다.

검사 시점, 갱신 위치, 탈출 경로를 함께 보면 while과 do-while의 차이도 더 선명해집니다.

종료 가능성은 모든 되돌아가는 경로에서 점검한다

skip=true를 명시한 한 반복에서 잘못된 continue 경로는 counter=0 유지, 수정 경로는 1로 증가한다. 독립된 두 프로그램의 진행 차이를 같은 프레임에서 비교한다.

C++ while 문에서 일반 본문 끝과 continue 경로가 모두 조건을 바꾸는 갱신에 도달하는지, false와 break 같은 탈출 경로가 실제로 도달 가능한지 확인하는 무한 반복 점검표

PROGRESS · BACK EDGE · EXIT

모든 되돌아가는 경로에서 진행과 종료를 확인한다

조건식을 한 번 읽는 것만으로는 종료를 보장할 수 없습니다. 조건으로 되돌아가는 모든 경로에서 다음 검사 결과가 달라질 수 있는지 확인합니다.

핵심 관계잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.갱신 우회갱신 통과while 검사counter=0skip=true인 회차continue본문 아래 ++이 경로는 생략수정 while 검사counter=0skip=true인 회차작업 생략++countercounter=1
핵심 관계잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.skip=true인 회차while 검사counter=0continue본문 ++생략수정 검사counter=0작업 생략++countercounter=1

잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.

관계도 해설과 예제 원자료

갱신을 건너뛸 수 있음

int counter = 0;
while (counter < 5) {
  if (skip()) continue;
  work();
  ++counter;
}

skip()이 계속 참이면 continue가 ++counter를 건너뛰어 조건은 계속 참입니다.

모든 정상 경로가 진행

int counter = 0;
while (counter < 5) {
  if (!skip()) work();
  ++counter;
}

일반 경로와 작업을 건너뛰는 경로가 모두 갱신을 지난 뒤 다음 조건 검사로 돌아갑니다.

  1. 검사 시점을 표시한다

    while과 for는 본문 전, do-while은 본문 후에 검사합니다. 어떤 값이 다음 결과를 결정하는지 적습니다.

  2. 되돌아가는 경로를 모두 추적한다

    본문의 정상 끝뿐 아니라 조건문, 중첩 블록, continue가 필요한 갱신을 우회하지 않는지 확인합니다.

  3. 탈출 경로의 범위와 도달성을 확인한다

    조건의 false는 반복을 끝냅니다. 이 장에서 다루는 문맥에서 break는 자신을 둘러싼 반복문 또는 switch 문 가운데 가장 안쪽 문만 끝내므로, 중첩 구조에서는 어느 문을 대상으로 하는지 따로 봅니다.

while (true)나 for (;;)는 조건으로 종료하지 않겠다는 제어 형태입니다. 내부에서 끝나야 하는 작업이라면 도달 가능한 break, return 같은 별도 종료 계약을 명시하고, 계속 실행하도록 설계한 작업이라면 그 수명과 외부 중단 방식을 문서화합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
두 코드 사본

skip=true인 회차를 같은 counter=0에서 비교한다.

  • skip: true
  • counter: 0
  • 잘못된 버전과 수정 버전은 독립된 실행이다.
continue 경로

증가 위치가 제어 경로의 차이를 만든다.

  • 잘못된 경로: counter 0 유지
  • 수정 경로: counter 1
  • while의 continue가 본문 아래 증가를 건너뛸 수 있다.
다음 검사

다음 반복 진입 상태를 나란히 읽는다.

  • 잘못된 상태: 진행 없음
  • 수정 상태: 진행됨
  • 생략 경로에서도 상태가 갱신되어야 같은 회차에 갇히지 않는다.

종료 가능성은 모든 되돌아가는 경로에서 점검한다

skip=true를 명시한 한 반복에서 잘못된 continue 경로는 counter=0 유지, 수정 경로는 1로 증가한다. 독립된 두 프로그램의 진행 차이를 같은 프레임에서 비교한다.

C++ while 문에서 일반 본문 끝과 continue 경로가 모두 조건을 바꾸는 갱신에 도달하는지, false와 break 같은 탈출 경로가 실제로 도달 가능한지 확인하는 무한 반복 점검표

PROGRESS · BACK EDGE · EXIT

모든 되돌아가는 경로에서 진행과 종료를 확인한다

조건식을 한 번 읽는 것만으로는 종료를 보장할 수 없습니다. 조건으로 되돌아가는 모든 경로에서 다음 검사 결과가 달라질 수 있는지 확인합니다.

핵심 관계잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.갱신 우회갱신 통과while 검사counter=0skip=true인 회차continue본문 아래 ++이 경로는 생략수정 while 검사counter=0skip=true인 회차작업 생략++countercounter=1
핵심 관계잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.skip=true인 회차while 검사counter=0continue본문 ++생략수정 검사counter=0작업 생략++countercounter=1

잘못된 while은 continue에서 ++counter를 건너뛴다. 수정 버전에서는 작업을 건너뛰어도 ++counter를 수행한 뒤 조건으로 돌아간다. 두 프로그램은 독립 비교다.

관계도 해설과 예제 원자료

갱신을 건너뛸 수 있음

int counter = 0;
while (counter < 5) {
  if (skip()) continue;
  work();
  ++counter;
}

skip()이 계속 참이면 continue가 ++counter를 건너뛰어 조건은 계속 참입니다.

모든 정상 경로가 진행

int counter = 0;
while (counter < 5) {
  if (!skip()) work();
  ++counter;
}

일반 경로와 작업을 건너뛰는 경로가 모두 갱신을 지난 뒤 다음 조건 검사로 돌아갑니다.

  1. 검사 시점을 표시한다

    while과 for는 본문 전, do-while은 본문 후에 검사합니다. 어떤 값이 다음 결과를 결정하는지 적습니다.

  2. 되돌아가는 경로를 모두 추적한다

    본문의 정상 끝뿐 아니라 조건문, 중첩 블록, continue가 필요한 갱신을 우회하지 않는지 확인합니다.

  3. 탈출 경로의 범위와 도달성을 확인한다

    조건의 false는 반복을 끝냅니다. 이 장에서 다루는 문맥에서 break는 자신을 둘러싼 반복문 또는 switch 문 가운데 가장 안쪽 문만 끝내므로, 중첩 구조에서는 어느 문을 대상으로 하는지 따로 봅니다.

while (true)나 for (;;)는 조건으로 종료하지 않겠다는 제어 형태입니다. 내부에서 끝나야 하는 작업이라면 도달 가능한 break, return 같은 별도 종료 계약을 명시하고, 계속 실행하도록 설계한 작업이라면 그 수명과 외부 중단 방식을 문서화합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
두 코드 사본

skip=true인 회차를 같은 counter=0에서 비교한다.

  • skip: true
  • counter: 0
  • 잘못된 버전과 수정 버전은 독립된 실행이다.
continue 경로

증가 위치가 제어 경로의 차이를 만든다.

  • 잘못된 경로: counter 0 유지
  • 수정 경로: counter 1
  • while의 continue가 본문 아래 증가를 건너뛸 수 있다.
다음 검사

다음 반복 진입 상태를 나란히 읽는다.

  • 잘못된 상태: 진행 없음
  • 수정 상태: 진행됨
  • 생략 경로에서도 상태가 갱신되어야 같은 회차에 갇히지 않는다.

예시

입력이 끝나도 종료되는 명령 읽기는 추출 결과를 조건에 넣을 수 있습니다. 아래 프로그램은 공백으로 구분한 hello와 exit 명령을 받으며, 한 줄 전체를 명령 하나로 읽는 방식은 아닙니다.

명령 또는 입력 종료로 끝나는 반복
#include <iostream>
#include <string>

int main() {
    std::string command;
    while (std::cin >> command) {
        if (command == "exit") {
            break;
        }
        if (command == "hello") {
            std::cout << "hello\n";
        } else {
            std::cout << "unknown\n";
        }
    }
    std::cout << "done\n";
}

hello exit을 입력하면 hello와 done을 한 줄씩 출력합니다. hello만 읽고 입력이 끝나도 다음 추출이 실패하여 hello와 done을 출력합니다. 입력 종료는 끝에 표시할 별도의 명령을 전송한 것이 아니라, 더 읽을 수 없다는 스트림 상태입니다. 문자열은 유지되어도 실패한 추출 뒤 본문에 다시 들어가지 않으므로 이전 명령을 재실행하지 않습니다.

검사 위치를 바꾸어 혼자 풀기

같은 초깃값 3에서 while (n < 3) { ++n; }와 do { ++n; } while (n < 3);의 본문 횟수와 마지막 n을 각각 적습니다. 초깃값을 0으로 바꾸면 두 반복의 결과가 같아지나요? 위 명령 프로그램에 hello를 읽히고 입력을 끝냈을 때 왜 clear()를 호출해 계속 기다리지 않는지도 설명해 보세요.

처음 검사와 정상 입력 종료 풀이

초깃값이 3이면 while은 본문을 0회 실행하고 최종값은 3입니다. do-while은 본문을 1회 실행하고 최종값은 4입니다. 초깃값이 0이면 둘 다 0·1·2 상태에서 본문을 총 3회 실행한 뒤 최종값이 3이 됩니다. 같은 결과가 나온 입력 하나로 두 구조가 항상 같다고 할 수는 없습니다. 명령 프로그램은 입력 종료를 작업 완료로 정했으므로 오류 상태를 무조건 풀어 재시도하지 않습니다.

예시 코드에서는 counter++가 조건을 바꾸는 갱신 지점입니다.

이 줄이 빠졌거나 continue 같은 분기가 갱신을 건너뛰어 조건이 계속 참으로 남는 상황은 초기 상태, 모든 되돌아가는 경로의 갱신 위치, 탈출 조건을 함께 확인하면 빠르게 찾을 수 있습니다.