IDL/Programming

WHILE 및 REPEAT 구문의 이해

이상우_idl 2023. 2. 10. 11:03
728x90
반응형

일반적으로 프로그래밍을 하면서 자주 하게 되는 작업 중 하나가 바로 반복 작업입니다. 물론 IDL에서도 여러가지 형태의 반복형 구문들이 지원됩니다. IDL에서 지원되는 반복형 구문들의 종류는 다음과 같습니다.

 

FOR

FOREACH

WHILE

REPEAT

 

FOR 구문은 횟수제어형 즉 반복의 횟수를 미리 정해놓고 반복을 수행하는 방식이며 일반적으로 가장 많이 사용되는 반복형 구문입니다. FOREACH 구문은 배열을 대상으로 그 원소들의 갯수만큼만 반복을 수행하는 방식의 구문이며 자세한 내용은 관련 게시물을 참조하시면 됩니다. 그리고 WHILE 및 REPEAT 구문은 횟수를 미리 정해놓지않고 그 대신 특정한 조건을 걸고 반복을 수행하는 방식으로서 오늘은 이 두 종류의 구문들에 관해서 소개를 해보기로 하겠습니다.

 

WHILE 구문과 REPEAT 구문은 특정한 조건을 걸고 반복을 수행한다는 점은 서로 유사합니다. 다만 구체적으로는 차이가 있는데 간단하게 요약해보면 다음과 같습니다.

 

WHILE 구문 : 특정한 조건을 걸고 이 조건이 충족되는 동안에만 반복을 계속 수행

REPEAT 구문 : 특정한 조건을 걸고 이 조건이 충족되는 순간이 올 때까지만 반복을 계속 수행

 

물론 이렇게 간략한 설명만으로는 충분하지않기 때문에 각각의 구문에 관해서 좀 더 자세히 살펴보겠습니다.

 

 

< WHILE 구문 >

 

먼저 WHILE 구문의 경우는 특정한 조건을 내걸고 이 조건이 충족되는 동안에만 반복을 수행한다고 설명을 했는데요. 즉 조건이 충족되는 동안 계속 반복을 수행하다가 어느 순간에 그 조건이 충족되지 않는 시점이 오면 그 때 반복을 종료하게 됩니다. 문법적으로는 WHILE 조건 DO BEGIN으로 시작하고 ENDWHILE로 끝납니다. 예제를 하나 들어보면 다음과 같습니다.

 

j = 0
WHILE j LT 10 DO BEGIN
  PRINT, j
  j = j+1
ENDWHILE

 

이 프로그램의 내용을 잘 봅시다. 맨 처음에 j라는 변수가 0으로 정의됩니다. 그리고 바로 WHILE 구문으로 이어지는데, 여기서는 "변수 j의 값이 10보다 작다"는 조건이 충족되는 동안은 계속 반복을 수행하게 됩니다. 반복되는 작업의 내용을 보면, 먼저 변수 j의 값을 출력하고 j의 값을 1만큼 증가시키게 됩니다. 그렇게 하면 j의 값이 처음에는 0이었지만 반복이 계속 진행됨에 따라 j의 값은 1씩 증가하게 됩니다. 그러다보면 j LT 10이라는 조건은 처음에는 충족되지만 반복이 계속되면서 j의 값이 점점 커지다보면 이 조건이 충족되지않는 순간이 결국 오게 될 것입니다. 그 때 비로소 반복이 종료되는 방식입니다. 실제로 위의 내용을 실행하면 출력 결과는 다음과 같습니다.

 

       0
       1
       2
       3
       4
       5
       6
       7
       8
       9

 

출력의 내용이 9에서 멈춘 이유를 잘 생각해보면, j가 9일 때에는 일단 이 값을 출력하고 1을 더한 후 다음 회차로 가면 j가 10이 되어있을텐데 그 때에는 이미 j LT 10이라는 조건이 거짓이 되어버리기 때문에 작업을 더 이상 수행하지 않게 되는 것입니다. 즉 WHILE이라는 문구는 처음에 제시되었던 조건이 충족되는 동안이라는 의미라고 보면 됩니다. 이러한 구문을 사용할 때 주의해야할 것은, 반복이 무한히 계속 진행되는 무한루프의 상황이 오지 않도록 사전에 신경을 써줘야한다는 것입니다. 만약 위의 내용에서 j가 1씩 증가되도록 하는 부분을 제거하게 될 경우를 가정해봅시다. 즉 다음과 같은 상황입니다.

 

j = 0
WHILE j LT 10 DO BEGIN
  PRINT, j
ENDWHILE

 

만약 이 상태로 실행을 하게되면 0이란 값을 출력하는 작업이 무한히 반복됩니다. 왜냐하면 j LT 10이란 조건이 거짓이 되는 상황이 절대로 오지않기 때문입니다. 이런 상황이 오면 그냥 강제로 종료하는 방법을 쓸 수 밖에 없게 됩니다. 따라서 WHILE 구문을 사용할 때에는 이런 부분을 반드시 유의해야 합니다. 나중에 소개할 REPEAT 구문의 경우도 마찬가지입니다. 그러면 이번에는 약간 더 응용을 해서, 1부터 10까지의 정수들의 총합을 산출하는 과정을 WHILE 구문으로 구현해봅시다. 그 내용은 다음과 같습니다.

 

j = 1
sum = 0
WHILE j LE 10 DO BEGIN
  sum = sum+j
  PRINT, j, sum
  j = j+1
ENDWHILE

 

앞선 예제 프로그램보다 약간 더 복잡해지긴 했지만 어쨌든 여기서는 sum이라는 변수를 추가하여 매 회차마다 그때까지의 값을 누적하여 중간총합을 구할 수 있도록 한 것입니다. 그러면서 j와 sum의 값을 매 회차마다 출력함으로써 전체 과정을 볼 수 있도록 하였습니다. 실행해보면 다음과 같은 결과가 출력될 것입니다.

 

       1       1
       2       3
       3       6
       4      10
       5      15
       6      21
       7      28
       8      36
       9      45
      10      55

 

이 내용을 보면 1부터 10까지의 정수들의 총합을 산출하는 전체 과정을 확인할 수 있습니다. 다시 한번 정리해보면 WHILE 구문은 조건을 하나 내걸고 처음에는 그 조건이 충족되는 상태로 반복을 시작한 다음 어느 시점에서 그 조건이 충족되지 않는 순간이 오면 반복을 종료하는 방식이라고 정리해볼 수 있습니다.

 

 

< REPEAT 구문 >

 

앞서 간략 설명에서는 REPEAT 구문의 경우는 특정한 조건을 내걸고 이 조건이 충족되는 순간이 올 때까지만 반복을 수행한다고 설명을 했는데요. 구체적으로는 처음에는 조건이 충족되지 않는 상태에서 계속 반복을 수행하다가 어느 순간에 그 조건이 충족되는 시점이 오면 그 때 반복을 종료하게 됩니다. 방식 자체가 WHILE 구문과는 정반대입니다. 그리고 문법적으로는 REPEAT BEGIN으로 시작하고 ENDREP UNTIL 조건로 끝납니다. 예제를 하나 들어보면 다음과 같습니다.

 

j = 0
REPEAT BEGIN
  PRINT, j
  j = j + 1
ENDREP UNTIL j GE 10

 

이 프로그램의 내용을 잘 봅시다. 맨 처음에 j라는 변수가 0으로 정의됩니다. 그리고 바로 REPEAT 구문으로 이어지는데, 여기서는 "변수 j의 값이 10보다 크거나 같다"는 조건이 충족되지 않는 동안에은 계속 반복을 수행하게 됩니다. 반복되는 작업의 내용을 보면, 먼저 변수 j의 값을 출력한 다음 그 값을 1만큼 증가시키게 됩니다. 그렇게 하면 j의 값이 처음에는 0이었지만 반복이 계속 진행됨에 따라 j의 값은 계속 증가하게 될 것입니다. 그러다보면 j GE 10이라는 조건은 처음에는 충족되지 않았지만 반복이 계속되다보면 이 조건이 충족되는 순간이 결국 오게 될 것입니다. 그 때 비로소 반복이 종료되는 방식입니다. 실제로 위의 내용을 실행하면 출력 결과는 다음과 같습니다.

 

       0
       1
       2
       3
       4
       5
       6
       7
       8
       9

 

출력의 내용이 9에서 멈춘 이유를 잘 생각해보면, j가 9일 때에는 일단 이 값을 출력하고 1을 더한 후 다음 회차로 가면 j가 10이 되어있을텐데 그 때가 바로 j GE 10이라는 조건이 드디어 충족되는 순간이기 때문에 작업을 더 이상 수행하지 않게 되는 것입니다. 즉 UNTIL이라는 문구는 처음에 제시되었던 조건이 충족되는 순간이 올 때까지라는 의미라고 보면 됩니다. 그리고 REPEAT 구문을 사용할 때 주의해야할 것은, 앞서 WHILE 구문의 경우와 마찬가지로 반복이 무한히 계속 진행되는 무한루프의 상황이 오지 않도록 사전에 신경을 써줘야한다는 것입니다. 만약 위의 내용에서 j가 1씩 증가되도록 하는 부분을 제거하게 될 경우를 가정해봅시다. 즉 다음과 같은 상황입니다.

 

j = 0
REPEAT BEGIN
  PRINT, j
ENDREP UNTIL j GE 10

 

이 상태로 실행을 하게되면 0이란 값을 출력하는 작업이 무한히 반복됩니다. 왜냐하면 j GE 10이란 조건을 만족하게 되는 순간이 절대로 오지 않을 것이기 때문입니다. 이런 상황이 오면 그냥 강제로 종료하는 방법을 쓸 수 밖에 없게 됩니다. 따라서 REPEAT 구문을 사용할 때에도 이런 부분을 반드시 유의해야 합니다. 그러면 이번에는 약간 더 응용을 해서, 1부터 10까지의 정수들의 총합을 산출하는 과정을 REPEAT 구문으로 구현해봅시다. 그 내용은 다음과 같습니다.

 

j = 1
sum = 0
REPEAT BEGIN
  sum = sum+j
  PRINT, j, sum
  j = j + 1
ENDREP UNTIL j GT 10

 

이 내용을 보면 1부터 10까지의 정수 총합을 산출하는 전체 과정을 확인할 수 있습니다. 앞서 WHILE 구문으로도 동일한 작업을 수행하는 예제를 봤었는데, 동일한 작업을 REPEAT 구문으로도 구현할 수 있음에 주목할 필요가 있습니다. 어쨌든 정리해보면 REPEAT 구문은 조건을 하나 내걸고 처음에는 그 조건이 충족되지 않는 상태로 반복을 일단 시작한 다음 어느 시점에서 그 조건이 충족되는 순간이 오면 반복을 종료하는 방식이라고 정리해볼 수 있습니다.

 

 

< 마무리 및 기타 >

 

지금까지 WHILE 및 REPEAT 구문에 관한 설명 및 관련 예제들을 살펴보았습니다. 반복 횟수를 미리 정해놓지 않은 상태에서 반복을 일단 시작한 다음 일정한 조건이 충족되지않는 또는 충족되는 순간에 반복을 종료한다는 방식을 잘 이해하면 다양한 용도로 활용할 수 있습니다. 그런 예제들 중 하나가 바로 텍스트(또는 ASCII) 형식의 외부 파일을 읽는 경우들 중에서 그 파일 내에 수록된 전체 데이터의 줄(Line) 수를 미리 짐작하기 어려운 경우입니다. 예를 들어 mydata.txt라는 텍스트 파일의 내용을 모두 읽어야하는데, 수록된 내용의 전체 줄 수를 미리 알지못하는 상태에서 이 파일을 처음부터 끝까지 읽어야하는 경우의 처리방법은 대략 다음과 같습니다.

 

OPENR, lun, 'mydata.txt', /GET_LUN

s = ''

WHILE ~EOF(lun) DO BEGIN

  READF, lun, s

  PRINT, s

ENDWHILE

FREE_LUN, lun

 

여기서는 EOF 함수를 사용하여 읽기의 대상이 되는 파일의 끝부분에 도달했는가 여부를 판별하고, 아직 도달하지 않은 동안에는 EOF(lun)의 값이 0이기 때문에 반복을 계속 수행하여 파일의 내용을 한 줄씩 읽고 출력하는 작업을 계속 진행됩니다. 그렇게 한 줄씩 읽는 작업을 반복하다보면 결국 파일의 맨 끝 부분에 도달하게 되는데, 이 때에는 EOF(lun)의 값이 1이 될 것이기 때문에 이 때 반복이 비로소 종료되는 방식입니다. 이러한 예제는 IDL 도움말에서 EOF 함수에 관한 내용에서도 제시되어있으므로 한번 참조해보시면 좋을 것 같습니다.

반응형