반복문

네 가지 반복문: for / while / repeat / for-in

아래 예시 코드를 먼저 확인하세요. 이전 수업의 코드 파일 mydemo.dpr을 수정한 뒤 확장자를 pas로 바꿔 mydemo.pas로 만듭니다. 이것은 파스칼 소스 파일의 표준 확장자입니다. 그 후 구문 강조 기능을 지원하는 노트패드++ 등 코드 편집 툴을 다운로드하면 코드 가독성이 훨씬 좋아집니다.

아래는 모든 코드 줄에 주석을 달아놓은 완전 실행 예제입니다. 코드 예시 뒤에 각 구문을 하나씩 순서대로 분석해 설명하겠습니다.

// 2.8 반복문: for, while, repeat, for..in
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
// FPC 컴파일러 지시자: 객체지향 모드 활성화, 긴 문자열 지원, 문자열 자동 참조 카운트 비활성화
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
// 윈도우 플랫폼 설정: 콘솔 전용 프로그램으로 지정(GUI 창 없음)
{$R+} // 배열 범위 검사 활성화, 인덱스 오류 디버깅에 매우 유용
var
  MyArray: array [0..9] of Integer; // 정수 배열, 인덱스 0~9 총 10개 요소
  I: Integer; // 반복문 카운터 변수
begin
// 1. 정방향 for 반복문: 배열 초기화, 0~9 각 수의 제곱값 저장
for I := 0 to 9 do
    MyArray[I] := I * I;

// 2. 기본 for 반복문으로 배열 인덱스 순회하며 제곱값 출력
for I := 0 to 9 do
    WriteLn('제곱값: ', MyArray[I]);

// 3. Low/High 함수로 배열 상하한선 자동 추출, 0과 9를 하드코딩하지 않아 확장성 좋음
for I := Low(MyArray) to High(MyArray) do
    WriteLn('제곱값: ', MyArray[I]);

// 4. while 반복문: 조건을 먼저 판단하고 조건이 참일 때만 반복 본문 실행
  I := 0;
while I < 10 do
begin
    WriteLn('제곱값: ', MyArray[I]);
    I := I + 1; // 동일한 표기법: I+=1 / Inc(I) 셋 다 동일 동작
end;

// 5. repeat-until 반복문: 본문을 한 번 실행한 뒤 마지막에서 종료 조건 확인
  I := 0;
repeat
    WriteLn('제곱값: ', MyArray[I]);
    Inc(I); // 카운터 변수 1 증가
until I = 10;

// 6. for-in 순회: 인덱스를 조작하지 않고 배열 요소 값 직접 추출
for I in MyArray do
    WriteLn('제곱값: ', I);
end.Code language: PHP (php)

아래는 모든 주석을 제거한 순수 코드입니다

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

for I := 0 to 9 do
    WriteLn('제곱값: ', MyArray[I]);

for I := Low(MyArray) to High(MyArray) do
    WriteLn('제곱값: ', MyArray[I]);

  I := 0;
while I < 10 do
begin
    WriteLn('제곱값: ', MyArray[I]);
    I := I + 1;
end;

  I := 0;
repeat
    WriteLn('제곱값: ', MyArray[I]);
    Inc(I);
until I = 10;

for I in MyArray do
    WriteLn('제곱값: ', I);

end.Code language: PHP (php)

이제 각 반복문의 코드 로직을 단계별로 분석하겠습니다

for 반복문

for 반복문을 이용해 배열에 값을 할당하기

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

end.Code language: PHP (php)

이 코드는 세 부분으로 나뉩니다. 상단은 전처리 명령문, 중간 var 섹션에서 변수(배열 하나, 정수형 변수 하나)를 선언하고 begin ~ end. 사이의 메인 실행 블록 안에 for 반복문이 존재합니다. 0부터 9까지 차례로 I에 할당한 뒤 인덱스를 통해 배열 요소에 값을 채워줍니다.

MyArray[0]부터 MyArray[9]까지 총 열 개의 배열 요소에 값을 일괄 입력합니다. 별표 *는 곱셈 연산자입니다.

MyArray[0] := 0 * 0;

MyArray[1] := 1 * 1;

MyArray[9] := 9 * 9;

그 다음 첫 번째 for 반복문 아래에 또 다른 for 반복문을 추가해서 배열 안에 저장된 각 요소 값을 읽어옵니다.

컴파일하고 실행하면 저장된 모든 값이 출력됩니다

출력되는 모든 수는 0~9의 제곱으로 위에서 예상한 결과와 일치합니다.

배열의 인덱스 범위를 모를 경우 내장 함수를 사용해 상한선과 하한선을 얻을 수 있습니다.

위의 Low(배열이름)은 배열의 최소 인덱스 값을 가져오는 함수입니다

  • Low(타입/변수): 서수형, 배열, 집합최솟값 / 하한선 반환
  • High(타입/변수): 서수형, 배열, 집합최댓값 / 상한선 반환

while과 repeat 반복문

while 안쪽 begin end;으로 감싼 반복 본문 마지막에서 변수 I의 값이 1 증가합니다. 증가 처리가 끝나면 코드 흐름이 while I < 10 do 행으로 돌아가 다시 조건을 검사합니다. 조건이 참이면 두 번째 반복 본문을 실행하고 다시 I가 1 증가한 뒤 재검사하는 과정을 반복합니다. I<10이 거짓이 되는 순간 while 반복문이 종료되는데, 즉 I가 10이 되면 빠져나갑니다.

while과 repeat-until 핵심 차이점

  1. 조건 판단 로직이 반대
  • while 조건 do: 조건 참 → 반복 계속, 조건 거짓 → 반복 종료
  • repeat ... until 조건: 조건 참 → 반복 종료, 조건 거짓 → 반복 계속
  1. 보장되는 실행 횟수가 다름
  • while: 최초 조건을 만족하지 못하면 반복 본문이한 번도 실행되지 않음
  • repeat-until: 조건과 상관없이반복 본문이 최소 한 번은 실행됨

C, C++, Java 등 언어를 공부했다면 쉽게 이해할 수 있습니다. repeat until은 do while과 기능이 거의 동일합니다. 반복 본문을 먼저 한 번 실행한 뒤 until 뒤 조건을 확인하고 조건이 거짓이면 다시 반복합니다.

repeat until에는 begin end가 필요하지 않으며 repeat ~ until 자체가 하나의 코드 블록을 구성합니다. 굳이 begin end를 추가해도 작동하지만 쓸 필요가 없습니다.

repeat until의 문자 그대로 뜻은 ‘반복하다 ~ 할 때까지’로 단어 의미만으로 동작 방식을 쉽게 파악할 수 있습니다.


순회 과정에서 MyArray 안의 값이 순서대로 I에 할당되므로 반복문 안에서 I를 직접 조작할 수 있습니다. 인덱스를 직접 증가시킬 필요가 없고 인덱스 자체를 사용하지 않아도 되며 모든 요소 순회가 끝나면 처리가 마무리됩니다.

일반 for 반복문(for I := ... to/downto) 설명

  1. C언어의 for 반복문과 유사하지만 제약이 더 강하며 연속된 서수형(정수, 열거형)만 순회 가능;
  2. downto 키워드로 역순 순회 지원: for I := 9 downto 0 do;
  3. 상하한선 함수 Low(변수) / High(변수)는 반복문 시작 시 딱 한 번만 계산돼 실행 효율이 높음;
  4. 반복문이 정상 종료된 후 변수 I의 값은 정의되지 않아 컴파일러 경고가 발생합니다. Break / Exit로 중도 탈출한 경우 I는 현재 값을 유지합니다.

for-in 순회(현대적 foreach 스타일)

인덱스를 직접 다루지 않고 네 가지 데이터 타입을 순회할 수 있습니다:

  1. 배열: 배열 안 각 요소 값을 직접 읽기(위 예제에서 시연 완료)
  2. 열거형
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

type TAnimalKind = (Duck,Cat,Dog);

var AK:TAnimalKind;
begin
  for AK in TAnimalKind do 
    WriteLn(AK);
end.Code language: PHP (php)
  1. 집합 타입
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}

type
  // 열거형 정의
  TAnimalKind = (Duck, Cat, Dog);
  // 열거형 기반 집합 타입 정의
  TAnimals = set of TAnimalKind;

var
  Animals: TAnimals;
  AK: TAnimalKind;
begin
  // 집합에 Duck, Cat 두 열거값 할당
  Animals := [Duck, Cat];

  // for-in으로 집합 내 존재하는 모든 멤버 순회
  for AK in Animals do
  begin
    WriteLn('발견한 동물: ', AK);
  end;
end.Code language: PHP (php)
  1. 제네릭 리스트(후속 장에서 학습)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
  SysUtils, Generics.Collections; // 제네릭 컨테이너 유닛 불러오기

type
  TMyClass = class  // 숫자와 제곱을 저장하는 커스텀 클래스
    I, Square: Integer;
  end;
  // 제네릭 객체 리스트 인스턴스화, 객체 생명주기 자동 관리
  TMyClassList = {$ifdef FPC}specialize{$endif} TObjectList&lt;TMyClass&gt;;
var
  List: TMyClassList;
  C: TMyClass;
  I: Integer;
begin
  List := TMyClassList.Create(true); // true: 리스트 소멸 시 내부 객체 자동 해제
try
  // 반복문으로 객체 생성 후 리스트에 추가
for I := 0 to 9 do
begin
      C := TMyClass.Create;
      C.I := I;
      C.Square := I * I;
      List.Add(C);
end;
  // for-in으로 리스트 안 모든 커스텀 객체 직접 순회
for C in List do
      WriteLn(C.I, '의 제곱은 ', C.Square, '입니다');
finally
    FreeAndNil(List); // 리스트 안전 해제, 메모리 누수 방지
end;
end.
Code language: HTML, XML (xml)

참고: 이 예제는 클래스와 제네릭을 사용하므로 초보자는 일단 건너뛰어도 무방합니다. 후속 객체지향 챕터에서 자세히 설명할 것입니다.

답글 남기기

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