QBasic 기초 시리즈

프로그램의 실행에는 기본적으로 세 가지의 제어 구조가 있습니다.

  1.  순차적 (Sequential)
  2. 선택 또는 의사결정 또는 조건부 (Selective or decision making or conditional)
  3. 반복 (Repetitive or iterative or looping)

1, 2번이 지금까지의 과정이며, 이 글에서는 3번에 대해 다뤄볼 것입니다.

 

예를 들어 불면증 때문에 잠을 잘 자기 위해 100마리의 양을 세는 프로그램을 만든다고 가정합시다. 그렇다면 지금까지 학습한 내용을 바탕으로 하면 다음과 같이 코드를 작성할 것입니다.

PRINT "양 1마리" 
PRINT "양 2마리"
PRINT "양 3마리"
PRINT "양 4마리"
PRINT "양 5마리"

.....

PRINT "양 98마리"
PRINT "양 99마리"
PRINT "양 100마리"

중략되어 있지만 양 100마리를 세기 위해 저런 식으로 일일히 복붙해서 100줄짜리 코드를 만들었습니다. 물론 맞는 코드입니다. 다만 코드 수가 너무 많아 공간 차지가 심하고, 똑같은 내용을 반복해서 써야 하기 때문에 프로그래머 입장에서도 매우 수고스럽고 비효율적입니다.

코드를 잘 보면 똑같은 PRINT 가 계속 반복되고 있을 뿐입니다. 그리고 내용도 “양 ?마리” 에서 숫자만 바뀌는 패턴입니다. 컴퓨터로 처리해야 되는 많은 작업중에는 이렇게 똑같거나 비슷한 내용이 수십번 이상 반복되는 반복 작업들이 대다수입니다. 반복문은 이러한 반복 패턴을 처리하기 위해 존재합니다.

 

반복문은 다음으로 구성됩니다.

  • 특정 변수의 초기화를 포함하는 진입점
  • 루프 연속 조건
  • 루프 바디
  • 출구 지점

적절한 초기화가 이루어지려면 항상 진입점에 반복문이 선언되어 있어야합니다. 루프 바디는 일반적으로 여러 번 실행되는 명령문으로 구성됩니다. 종료점은 루프 바디 다음에 오는 첫 번째 명령문입니다. 반복 횟수는 루프 연속 조건에 의해 제어되며, 루프 연속 조건은 루프 바디를 실행할 때마다 한 번씩 테스트됩니다.

 

QBasic 에는 세 가지 반복 구조가 있습니다.

  1. While … Wend Loop
  2. Do … Loop {While/Until} Loop
  3. For Loop

세 가지 방법에는 각자 장단점이 있습니다.

 

While … Wend 반복문

이 반복문은 루프 연속 조건을 만족(true)하는 경우에만 실행하는 사전 테스트 루프(pre-test loop)입니다.  루프 바디 실행 전에 조건을 검사하며, 조건을 만족하지 못하는 경우 절대 실행되지 않습니다.

While (조건문) 
    루프 바디
Wend

이 반복문이 유한하려면 조건이 중간에 변해야 합니다. 만약 조건이 항상 true라면 이 반복문은 영원히 끝나지 않는 무한 반복문이 됩니다. 따라서 무한 반복이 되게 하지 않으려면 조건이 바뀔 수 있는 반복문 외부에 위치한 변수가 필요하게 됩니다.

위의 양 세기 예제를 WHILE 반복문으로 바꾸면 다음과 같습니다.

DIM i AS INTEGER
i = 1
WHILE (i <= 100)
    PRINT "sheep = "; i
    i = i + 1
WEND

중요한 것은 1라인과 5라인입니다. i는 현재 몇 회째 반복되고 있는지를 세는 카운터 변수입니다. 그리고 i = i + 1은 반복될 때마다 카운터 변수 i를 1씩 증가시킵니다. 반복문이 반복될 때마다 i가 1씩 증가하며, 이런 식으로 증가해서 i가 101이 된다면 조건문이 거짓이 되기 때문에 반복을 더 이상 하지 않고 종료하게 됩니다. 이 부분이 없다면 i는 반복문이 아무리 반복되더라도 계속 1이기 때문에 조건문이 항상 참이라 무한 반복되게 됩니다.

 

Do … Loop {While/Until} Loop

WHILE문과 비슷한 역할을 하는데 차이점이라면 사후 테스트(post-test) 반복문이라는 점입니다. 이 반복문은 조건문과 상관없이 일단 루프 바디를 최초로 한 번 실행합니다. 그리고 실행 후 조건을 검사하고, true라면 반복을 계속, 아니라면 종료합니다. 이 반복문은 WHILE 문에 비해 거의 쓰이지 않지만, 참거짓 여부와 무관하게 최초에 한 번은 무조건 실행해야 하거나 하는 등의 작업에서 간혹 사용됩니다.

DIM i AS INTEGER
i = 1
DO
    PRINT "sheep = "; i
    i = i + 1
LOOP WHILE (i <= 100)
END

LOOP에서 whileuntil의 사용처가 다릅니다. loop while은 위와 같이 조건이 true인 경우 계속 반복됩니다. 반면 until은 조건이 최초로 true가 되는 순간 이후 작업을 진행하지 않고 바로 종료시킵니다. 만약 이 예제를 Loop until로 바꾸려면 LOOP WHILE (i = 101) 로 해야 합니다. true가 되면 do 문을 바로 종료시키기 때문에 i = 100으로 한다면 99마리까지만 나오게 됩니다.

 

For Loop 반복문

가장 중요한 반복문입니다. while 문 예제를 보면  카운터 변수와 이 카운터 변수를 증가시키는 식 두 가지가 있는 것을 알 수 있습니다. 반복문이 꼭 숫자 세기같은 유형에서만 사용하는 것은 아니지만, 다수의 반복 작업은 저런 식의 숫자 세기가 주류입니다. For Loop 문은 이러한 숫자세기류 반복작업에 특화되어 있는 반복문입니다.

FOR 카운터변수 = 시작 TO 끝 [STEP 카운터변수 증감] 
    [명령문 블록]
NEXT [카운터변수]

일반적으로 대부분 언어에서 For 반복문의 특징이라면 카운터변수를 외부에서 선언하지 않고 For문 안에서 선언하는 것이 가능합니다. 이렇게 선언된 카운터변수는 For 문 안에서 사용됩니다. 다만 QBasic은 다른 언어와 달리 카운터변수의 스코프가 For문 안에서만 한정되지 않는데, 이 문제는 지금 다룰만한 주제가 아니므로 넘어가겠습니다. 양 세기 예제를 For문으로 바꾸면 다음과 같이 됩니다.

FOR i = 1 TO 100
    PRINT "sheep = "; i
NEXT i

같은 내용인데 For문을 사용하니 훨씬 간단해졌습니다. i = 1 TO 100 은 i의 최초값을 1로 설정한 다음 이 변수가 100이 될 때까지 반복하겠다는 의미이며, NEXT i는 변수값을 증가시킨다는 의미입니다. STEP을 지정하지 않으면 기본값은 1이 됩니다.

 

For문은 증가뿐만 아니라 감소되는 숫자 세기도 할 수 있고, STEP을 통해 일정 간격으로 건너뛰기도 할 수 있습니다.

FOR i = 15 TO -77 STEP -15
    PRINT i
NEXT i

 

1에서부터 1000까지를 전부 더한 값이 얼마인지도 For문을 통해 쉽게 알 수 있습니다.

DIM sum AS LONG
FOR i = 1 TO 1000
    sum = sum + i
NEXT i
PRINT sum

' 출력: 500500

 

팩토리얼 구하기 예제입니다.

REM CALCULATE FACTORIAL OF N.
CLS
DIM I, N AS INTEGER, FACT AS LONG
INPUT "ENTER N : "; N
FACT = 1

FOR I = 1 TO N
    FACT = FACT * I
NEXT I

PRINT " N! = "; FACT
END

 

갯수를 입력하면 갯수만큼 짝수 / 홀수를 나열하는 예제입니다.

REM PRINT 1st N TERMS OF ODD/EVEN NUMBER
DIM I, J, N AS INTEGER

INPUT "ENTER N "; N

PRINT "1ST N ODD NUMBERS ARE AS FOLLOWS "
J = 1
FOR I = 1 TO N
    PRINT J
    J = J + 2
NEXT I

PRINT "1ST N EVEN NUMBER ARE AS FOLLOWS "
J = 0
FOR I = 1 TO N
    PRINT J
    J = J + 2
NEXT I

END

 

위의 예제 외에도 반복문으로 할 수 있는 것은 매우 많습니다. 반복문만 알아도 많은 작업들을 수행할 수 있습니다.

QBasic 기초 시리즈

문의 | 코멘트 또는 yoonbumtae@gmail.com


카테고리: etc.


0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다