4-3-나.제어문 비교

여기까지 for, while, do~while 세가지 반복문에 대해 알아보았다. 세 종류 모두 비슷한 명령을 여러 번 반복한다는 근본적인 목적은 동일하지만 형식이 조금 다를 뿐이다. 비슷한 반복문을 쓸데없이 이렇게 많이 만들어 놓았을 리는 없고 세 종류가 약간씩 다른 차이점이 있다. 그래서 실무에서 제어 구조를 작성할 때 상황에 따라 적절한 반복문을 선택해서 사용해야 한다. 각 반복문의 특징과 차이점에 대해 연구해 보자.

 

for문 : 가장 큰 특징은 제어 변수를 사용한다는 점이다. 루프를 통제하는 변수를 선언하고 이 변수가 일정한 범위의 값을 가지는 동안 명령을 계속 반복한다. 그래서 통상 for문은 반복 횟수가 이미 정해져 있고 루프 중간에서 탈출하는 경우가 별로 없다. 물론 break문으로 강제로 탈출할 수도 있지만 일반적으로 반복 횟수가 정해져 있다. 그래서 for문은 1~100까지, 1번 학생~60번 학생까지의 경우처럼 미리 정해진 횟수만큼 반복할 때 가장 편리하다. 또한 문장안에 초기식, 조건식, 증감식이 포함되어 있어서 루프의 선두만 봐도 변수의 변화를 쉽게 파악하고 변경할 수 있다.

while문 : 루프를 계속할 조건만 있고 초기식이나 증감식이 없다. 아예 제어 변수라는 개념이 없으며 루프 내부에서 조건식의 진위 여부를 변경해야 한다. 그래서 while문은 반복 횟수가 가변적이다. 사용자의 입력이나 네트워크의 변화, 특정 신호의 입력 등 언제 발생할지 모르는 조건에 대해 반복할 때는 while문을 쓰는 것이 적합하다.

do~while : while문과 마찬가지로 제어 변수가 없고 반복 횟수가 가변적이지만 조건을 점검하는 시기가 다르다. while문은 루프로 들어가기 전에 조건을 점검하지만 do~while문은 일단 명령을 실행한 후 루프 계속 여부를 점검한다. 그래서 while문은 조건에 따라 한 번도 실행되지 않을 수도 있지만 do~while문은 최소한 한 번은 실행된다는 차이점이 있다. 요약하자면 while문은 선평가 후실행문이며 do~while문은 선실행 후평가문이다.

 

세가지 반복문은 상호 대체성이 있어서 for문 대신 while문을 쓸 수도 있고 while문 대신 do~while을 쓰는 것도 가능하다. 다음은 for문을 동일한 while문으로 변환하는 공식이다.

 

for (초기식;조건식;증감식) {

     명령;

}

초기식;

while(조건식) {

     명령;

     증감식;

}

 

초기식을 먼저 실행하고 루프로 진입하며 매 명령을 실행할 때마다 증감식을 실행하면 while문으로도 for문과 똑같은 구조를 만들 수 있다. 물론 완전히 같지는 않아서 루프 내부에서 continue명령을 사용할 때의 효과가 약간 달라진다. 반대로 while (조건) 명령;도 for (;조건;) 명령; 형식으로 변환할 수 있다. 제어문에 따른 실행 속도나 코드의 크기는 거의 차이가 없으므로 실행 속도는 제어문을 선택하는 기준이 아니다.

하지만 어느 쪽이 더 효율적이고 코드의 가독성이 높은지, 부작용은 없는지를 비교해 보면 세가지 반복문 중 가장 적절한 것이 있을 것이다. 세가지 제어 구조의 특징을 잘 파악해야 상황에 가장 적절한 반복문을 선택할 수 있다. 1~100까지 숫자의 합계를 구하는 루프는 for문이 가장 적당하다. 반복 범위가 미리 정해져 있고 이 값이 루프내에서 사용되어야 하므로 제어 변수를 쓰는 것이 효율적이며 코드도 훨씬 더 짧고 명료하다.

2장에서 만들었던 숫자 맞추기 게임에서는 사용자가 입력한 숫자와 컴퓨터가 생각한 숫자를 비교하는 명령이 do~while 루프로 싸여 있다. 이 경우 왜 do~while 루프가 가장 적절한가 하면 일단 사용자로부터 값을 입력받아야만 루프를 탈출할 것인지 계속할 것인지를 결정할 수 있기 때문이다. 즉, 조건을 점검하기 전에 일단 사용자로부터의 입력을 최소한 한 번은 먼저 받아야만 하는 것이다. 만약 이 프로그램을 while문으로 작성했다고 해 보자.

 

while (input!=num) {

     scanf("%d",&input);

     ....

}

 

이렇게 되면 정수값을 입력받기도 전에 input이 num과 같은지를 비교해야 하는데 이때 input이 가진 값은 초기화되지 않은 쓰레기값이기 때문에 정상적인 비교가 되지 않는다. 그래서 이 경우는 선평가 후실행문인 while은 적절하지 못하며 선실행 후평가문인 do~while이 적절하다.

세 반복문의 순서도를 그려보면 다음과 같다. 조건 평가와 명령을 실행하는 순서, 제어 변수에 대한 처리 등에 있어서 각각 고유한 특징이 있는데 이 순서도를 보고 자신이 이해한 것과 같은지 비교, 정리해 보자.

순서도를 보면 반복문들이 어떤 특징을 가지고 있는지 일목 요연하게 정리될 것이다.