C 언어 | 흐름 제어 | while문

while 문은 조건이 참일 때, 지정한 코드를 반복한다. 여기에서는 while 문을 이용한 반복의 제어 방법을 설명한다.

루프 만들기

프로그램 제어에서 분기와 마찬가지로 매우 중요한 존재가 반복 처리이다. 복잡한 계산이나 검색 등, 실전 프로그램에서 여러번 사용되므로 확실히 기본을 익힐 필요가 있다. 반복 처리는 특정 문장을 지정한 조건이 충족될 때까지 반복하여 수행한다. 이를 수행하는 가장 간단한 방법은 while 문을 이용한 방법이다.

while은 if 문에 유사한 구문으로, 조건식이 참이면 지정된 문장을 반복하는 것이다. 반대로 말하면 while은 조건식의 판단 결과가 거짓이 즉, 0이 될 때까지 문장을 반복한다.

while 문

while(조건식) 문장

조건식이 거짓이 될 때까지 문장이 실행되므로, 일반적으로 while 문장에서 조건식에 영향을 주는 변수 등을 조작하여 카운터의 역할을 갖게 한다. 카운터가 되는 변수를 사용하여, 문장 반복 횟수와 현재 몇 번째 반복인지를 알 수 있다.

코드 1

#include <stdio.h>

int main() {
  int iCount;
 printf("반복 횟수를 입력하십시오. >");
 scanf("%d" , &iCount);

  while(iCount > 0) {
   printf("카운터 = %d\n" , iCount);
   iCount--;
 }
 return 0;
}

코드1을 실행하면 반복 횟수를 요구하고 숫자를 입력하면, while은 입력된 값을 저장한 iCount을 확인하여 이것이 0이상이면 문장을 반복한다. while의 본체 문장에서는 카운터 값을 표시한 다음에 카운터 값을 감소시키고 있다. 이것을 반복하다 보면 카운터는 언젠가 0이 되고, 그러고 루프를 빠져 나온다.

무한 루프가 되어 버린 경우는 프로그램을 종료시키는 수단이 없다. 도중에 강제로 루프에서 벗어나려면, while 확인하고 있는 조건식이 거짓이 되도록 카운터를 조작하거나, break 문을 사용하여 while에서 강제로 나갈 수 있다. break 문은 제어를 벗어나 기능이 있기 때문에, 현재의 루프에서 벗어날 수 있다.

코드2

#include <stdio.h>

int main() {
  int iCount = 0;
 while(1) {
    if (iCount == 1000) break;
    printf("iCount = %d\n" , iCount++);
  }
 return 0;
}

코드2는 의도적으로 while의 조건식을 1(true)하여 무한 루프로 돌도록 하고, while을 빠져 수단으로 break 문을 사용하고 있다. iCount 변수의 값을 반복할 때마다 증가하고 이것이 1000에 도달하면 빠져 있다.

증가 처리는 printf("iCount = %d\n" , iCount++);에서 수행하고 있다. 초보자에게는 별로 익숙하지 않은 작성법이기 때문에 조금 설명하겠다. 이것은 두 줄로 나누어 다음과 같이 쓸 수도 있지만, 이 프로그램에서는 굳이 printf() 함수의 인수로 증가하고 있다.

printf("iCount = %d\n" , iCount);
iCount++;

이렇게 써서 문제는 없지만, 필자는 해설서 등에서 긴 소스 프로그램을 보면 피곤하므로, 불필요한 처리 및 중복 부분은 없애려고 노력하고 있다. 따라서 위의 두줄을 한줄로 정리하는 방법으로, printf() 함수의 인수로 지정하고 있는 iCount를 잘 살펴보면, printf()에서 사용된 후에 증가되도록 후위 증가 연산자를 사용했다. 후위 증가 연산자는 변수를 사용한 후에 증가하는 특징이 있었다는 것을 기억하도록 하자.

덧붙여서, while와 같은 반복 제어는 중첩해도 문제는 없다. 실용적인 프로그램은 복잡한 알고리즘과 그래픽 처리 등에서 비번히 중첩된 반복 제어를 수행한다.

while (expr1) {
  while (expr2) {
   ...
 }
}

이러한 중첩된 반복 처리는 응용 프로그램 개발은 결코 드문 일이 아니다. 예를 들어, 2차원의 정보에 대한 계산을 할 때, 반복 처리를 중첩하여 순서대로 계산하는 방법을 사용하고 있다. 이것은 2차원 컴퓨터 그래픽에 대한 전반적인 처리를 할 때 등에 응용할 수 있을 것이다. 다음 프로그램은 구구단 표를 만들어 화면에 표시한다.

코드3

#include <stdio.h>

int main() {
  int iOp1 = 1 , iOp2 = 1;

  while (iOp1 < 10) {
   while(iOp2 < 10) {
      printf("%2d " , iOp1 * iOp2);
     iOp2++;
   }
   printf("\n");
    iOp2 = 1;
   iOp1++;
 }
 return 0;
}

코드3을 실행하면 구구단 표가 출력된다.

덧붙이자면, printf() 함수의 형식 제어으로 %2d라는 표현이 있는데, 이 2라는 숫자는 문자 폭을 지정하고 있다. 이 경우는 %d를 지정했을 때와 동일하게 정수 값을 표시하지만, 문자 폭을 지정하고 있기 때문에, 최소 2문자의 폭을 사용하여 숫자를 표시한다. 1자리의 경우는 2문자에 못 미치기 때문에 공백으로 채워진다. 이것은 단순히 구구단 표를 아름답게 표시하기 위해 사용했을뿐, 그다지 중요하지 않다.

루프의 맨 위로 돌아가기

어떠한 사정으로 반복 처리의 복합 문장의 내부에서 처리를 중단하고, 다음 반복으로 넘어가고 싶은 경우가 있다. 즉, 현재의 반복은 그 시점에서 종료하고, while 문의 처음으로 돌아 표현식을 판단하고자 하는 상황이다.

이를 실현하려면 continue 문을 사용한다. 이것을 사용하면 문장의 나머지 처리를 수행하지 않고 루프의 선두로 돌아올 수 있다.

코드4

#include <stdio.h>

int main() {
 int iCount = 0;

 while(iCount++ < 100) {
   if (iCount % 2) continue;
   printf("%d " , iCount);
 }
 return 0;
}

이 프로그램은 화면에 짝수만 표시한다. 카운터 변수인 iCount를 2로 나눈 나머지가 0이 아닌 경우, 이는 즉 홀수인 경우라고 생각할 수 있으며 iCount % 2을 구하고, 이것이 참이라면 continue 문을 사용하여 나머지 처리는 무시한다. 그 결과 printf()가 실행되는 것은 iCount가 짝수인 경우만 이다.