Menu

C 언어 while 반복문: 문법, 예제, 흔한 실수

C의 while 반복문이 조건이 바뀔 때까지 반복하는 방법 - 조건 먼저 규칙, 센티널 반복문, EOF까지 입력 읽기, while(1), 그리고 for와 while 사이의 변환.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

횟수 없이 반복하기

for 반복문은 몇 번 돌아야 하는지 알거나 계산할 수 있을 때 맞는 도구입니다. 하지만 많은 일에는 횟수가 딸려 오지 않습니다. 파일이 끝날 때까지 모든 줄 읽기. 맞을 때까지 비밀번호 계속 묻기. 1이 될 때까지 숫자를 반으로 줄이기. 이럴 때 질문은 "몇 번"이 아니라 "언제까지"이고, 그것이 바로 while이 표현하는 것입니다.

아무도 미리 "일곱"을 계산하지 않았습니다. 반복문은 그저 조건이 성립하는 동안 계속 돌 뿐입니다.

문법과 조건 먼저 규칙

while (condition) {
    // 본문 - 조건이 0이 아닌 동안 실행됨
}

조건은 첫 번째를 포함해 매 통과 전에 검사됩니다. 결과가 셋 있습니다.

  • 조건이 처음부터 거짓인 반복문은 0번 실행됩니다. while (0) { ... }는 본문을 절대 실행하지 않습니다.
  • 조건이 검사하는 것이 무엇이든 반복문 전에 초기화되어 있어야 합니다. 아니면 쓰레기 값을 검사하는 셈입니다.
  • 본문의 무언가가 결국 조건을 거짓으로 만들어야 하며, 아니면 반복문이 끝나지 않습니다.

if처럼 괄호는 필수이고 그 뒤에 세미콜론은 없습니다. 그 어긋난 세미콜론은 같은 버그의 반복문 판입니다.

/* 버그: 빈 문장이 본문이다 - 영원히 돈다 */
while (i < 10);
{
    printf("%d\n", i);
    i++;
}

i가 증가되지 않으므로 조건이 결코 바뀌지 않습니다. gcc -Wall이 빈 본문을 지적합니다.

C의 참 판정 규칙은 if/else에서와 똑같이 적용됩니다. 식이 0이 아닌 동안 반복이 이어지고, 0이 되면 멈춥니다.

표준 모양: 초기화, 검사, 갱신

거의 모든 올바른 while 반복문은 세 곳에 흩어진 세 조각을 가지고 있습니다.

for 헤더가 담고 있는 바로 그 세 부분이, 한 줄에 모이지 않았을 뿐입니다. 여기서 "for인가 while인가"에 대한 정직한 답이 나옵니다. 세 조각이 모두 카운터 하나에 대한 것이라면 for가 그것들을 읽는 사람이 함께 확인할 수 있는 자리에 놓아 줍니다. 갱신이 긴 본문 곳곳에 흩어져 있거나 조건이 횟수가 아닌 무언가에 관한 것이라면 while이 더 명확한 형태입니다.

세 번째 조각을 잊는 것이 바로 그 while 버그입니다. 반복문이 멈추지 않으면 가장 먼저 확인할 것은 본문이 정말 조건이 읽는 것을 바꾸는지입니다.

센티널 반복문

센티널은 "멈춰"를 뜻하는 특별한 값입니다. 사용자가 0을 넣을 때까지 숫자를 더해 봅시다.

0 뒤의 99에는 절대 닿지 않습니다. 센티널이 반복문을 끝냈습니다. 숫자의 개수가 미리 알려져 있지 않다는 점을 보세요. 바로 그래서 이것이 while입니다.

C 문자열도 같은 방식으로 동작합니다. '\0' 센티널로 끝나므로, 문자열을 훑는 것은 교과서적인 while입니다.

EOF까지 입력 읽기

실무에서 가장 흔한 while은 더 이상 없을 때까지 입력을 읽는 것입니다. 규칙은 입력 함수가 저장한 값이 아니라 반환값을 검사하는 것입니다.

getchar는 다음 문자를, 입력이 다하면 상수 EOF를 반환합니다.

중요한 세부 사항이 둘 있습니다. cint인 이유는 EOF가 많은 시스템에서 char에 들어가지 않는 음수 값이기 때문입니다. char로 선언하면 비교가 절대 성립하지 않을 수 있습니다. 그리고 대입이 조건 안에 들어 있습니다. (c = getchar()) != EOF는 한 글자를 읽고, 저장하고, 비교하는 일을 한 단계로 합니다. 안쪽 괄호는 필수인데, !==보다 강하게 묶이기 때문입니다. 괄호가 없으면 비교 결과를 c에 저장하게 됩니다. 조건 안의 대입이 버그가 아니라 관용구인 몇 안 되는 자리 중 하나입니다.

같은 모양이 scanf에도 통합니다. 반환값이 성공적으로 변환한 항목의 개수입니다.

int n;
while (scanf("%d", &n) == 1) {
    /* n은 유효한 숫자를 담고 있다 */
}

이 반복문은 파일 끝에서 끝나고 숫자가 아닌 첫 입력에서도 끝나는데, 보통 그것이 바라는 바입니다.

쓰지 말아야 할 것while (!feof(f))입니다. feof는 읽기가 이미 실패했는지를 보고하므로, 마지막 항목 위에 있을 때는 아직 거짓이고, 본문이 한 번 더 돌고, 읽기가 실패해 오래된 데이터를 처리하게 됩니다. 읽기 자체를 검사하세요.

while (1)과 break

때로는 빠져나갈 조건이 본문 한가운데 - 읽은 뒤, 처리하기 전 - 에서만 알려집니다. 관용적인 답은 명시적인 탈출구가 있는 의도적 무한 반복문입니다.

while (1)은 항상 참이므로 나가는 길은 break(또는 return, exit)뿐입니다. 같은 목적으로 for (;;)를 쓰는 것도 보게 될 텐데, 둘은 같은 것으로 컴파일되고 어느 쪽을 선호하는지는 스타일 문제입니다.

탈출 검사가 정말로 본문 한가운데에 속할 때 이 모양을 쓰세요. 검사가 자연스럽게 맨 위에 맞는다면 읽는 사람이 볼 수 있도록 조건에 넣으세요. 유일한 break가 첫 문장인 while (1)은 그저 변장한 조건일 뿐입니다.

for와 while 사이의 변환

어떤 for 반복문도 while 반복문으로 쓸 수 있고 그 반대도 됩니다. 대응은 기계적입니다.

/* for */                          /* 동등한 while */
for (init; cond; update) {         init;
    body;                          while (cond) {
}                                      body;
                                       update;
                                   }

그래서 다음 둘은 같은 것을 출력합니다.

이 동등성이 새는 한 곳이 continue입니다. for 반복문에서 continue는 헤더의 갱신으로 점프하므로 카운터가 여전히 전진합니다. while 판에서는 continue가 곧장 조건으로 되돌아가면서 본문 끝의 i++를 건너뜁니다. 즉시 무한 반복입니다.

/* 버그: continue가 i++를 건너뛰어, 첫 짝수에서 영원히 돈다 */
int i = 0;
while (i < 10) {
    if (i % 2 == 0) {
        continue;
    }
    printf("%d ", i);
    i++;
}

while 반복문이 continue를 쓴다면 갱신이 그 앞에서 일어나는지 확인하세요. 아니면 헤더가 그것을 보장해 주는 for를 쓰세요.

흔한 함정

  • 아무것도 조건을 갱신하지 않음. 본문이 조건이 읽는 것을 바꿔야 합니다. 프로그램이 멈추면 여기부터 보세요.
  • 헤더 뒤의 세미콜론. while (cond);는 빈 문장을 본문으로 만듭니다.
  • 초기화한 적 없는 변수를 검사. 조건이 본문보다 먼저 실행되므로, 읽는 값이 이미 존재해야 합니다.
  • getcharint 대신 char. EOFchar에 들어가지 않습니다. 비교가 절대 참이 되지 않거나, 멀쩡한 바이트가 EOF로 오인될 수 있습니다.
  • while (!feof(f)). 한 번 더 돕니다. 읽기를 검사하세요.
  • 본문이 최소 한 번은 돈다고 가정. 그렇지 않습니다. 보장된 한 번의 통과가 필요할 때 - 선택을 확인하기 전에 메뉴를 출력하는 것처럼 - 그것이 do-while 반복문입니다.

자주 묻는 질문

C에서 while 반복문은 어떻게 작성하나요?

while (조건) { 본문 }입니다. 조건은 매 통과 전에 검사되므로, 본문은 조건이 0이 아닌 동안에만 실행되고 처음부터 거짓이면 한 번도 실행되지 않습니다. 본문 안의 무언가가 결국 조건을 바꿔야 하며, 그렇지 않으면 반복문이 끝나지 않습니다.

C에서 for와 while의 차이는 무엇인가요?

표현력은 같습니다. 어떤 forwhile로 다시 쓸 수 있습니다. 카운터와 한계, 단계가 한 헤더에 함께 속할 때는 for를, 멈추는 조건이 횟수가 아닐 때는 while을 쓰세요. 파일 끝까지 읽기, 성공할 때까지 재시도하기, 플래그가 뒤집힐 때까지 돌기가 그렇습니다.

C에서 EOF까지 입력을 읽으려면 어떻게 하나요?

읽은 값이 아니라 입력 함수의 반환값을 검사하세요. while (scanf("%d", &n) == 1) { ... }은 파일 끝이나 숫자가 아닌 첫 입력에서 멈추고, while ((c = getchar()) != EOF) { ... }은 한 글자씩 읽습니다. while (!feof(f))로 돌리지 마세요. 끝을 지나 한 번 더 실행됩니다.

제 while 반복문이 왜 무한히 도나요?

보통 본문의 어떤 것도 조건이 검사하는 값을 바꾸지 않기 때문이거나, 헤더 뒤에 세미콜론이 붙어(while (i < 10);) 빈 문장이 본문이 되었기 때문입니다. 둘 다 깔끔하게 컴파일되므로, 본문이 정말로 조건의 변수를 갱신하는지 확인하세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기