네 가지 반복문: 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 핵심 차이점
- 조건 판단 로직이 반대
while 조건 do: 조건 참 → 반복 계속, 조건 거짓 → 반복 종료repeat ... until 조건: 조건 참 → 반복 종료, 조건 거짓 → 반복 계속
- 보장되는 실행 횟수가 다름
- 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) 설명
- C언어의 for 반복문과 유사하지만 제약이 더 강하며 연속된 서수형(정수, 열거형)만 순회 가능;
- downto 키워드로 역순 순회 지원:
for I := 9 downto 0 do; - 상하한선 함수
Low(변수)/High(변수)는 반복문 시작 시 딱 한 번만 계산돼 실행 효율이 높음; - 반복문이 정상 종료된 후 변수 I의 값은 정의되지 않아 컴파일러 경고가 발생합니다.
Break/Exit로 중도 탈출한 경우 I는 현재 값을 유지합니다.
for-in 순회(현대적 foreach 스타일)
인덱스를 직접 다루지 않고 네 가지 데이터 타입을 순회할 수 있습니다:
- 배열: 배열 안 각 요소 값을 직접 읽기(위 예제에서 시연 완료)
- 열거형
{$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)

- 집합 타입
{$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)

- 제네릭 리스트(후속 장에서 학습)
{$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<TMyClass>;
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)
참고: 이 예제는 클래스와 제네릭을 사용하므로 초보자는 일단 건너뛰어도 무방합니다. 후속 객체지향 챕터에서 자세히 설명할 것입니다.