Vier Schleifentypen: for / while / repeat / for-in
Sehen Sie sich zuerst die folgenden Beispiele an. Ändern Sie die Codedatei aus der vorherigen Lektion, mydemo.dpr, und ändern Sie die Dateiendung zu pas, also mydemo.pas. Das ist die Standard-Endung für Pascal-Quelldateien. Laden Sie anschließend einen Code-Editor wie Notepad++ mit Syntaxhervorhebung herunter – dadurch wird der Code deutlich übersichtlicher.
Unten finden Sie ein vollständiges Beispiel mit Zeilenkommentaren. Nach dem Codebeispiel erklären wir jede Anweisung Schritt für Schritt.
// 2.8 Schleifenanweisungen: for, while, repeat, for..in
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
// FPC-Compilerdirektiven: Objektmodus aktivieren, lange Strings, automatische String-Referenzzählung deaktivieren
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
// Windows-Plattform: Programm als Konsolenanwendung markieren (kein GUI-Fenster)
{$R+} // Bereichsprüfung aktivieren, sehr hilfreich zum Debuggen von Array-Indexfehlern
var
MyArray: array [0..9] of Integer; // Ganzzahlarray mit 10 Elementen, Indizes 0 bis 9
I: Integer; // Schleifenzähler-Variable
begin
// 1. Aufsteigende for-Schleife: Array initialisieren, Quadrate von 0 bis 9 speichern
for I := 0 to 9 do
MyArray[I] := I * I;
// 2. Einfache for-Schleife zum Durchlaufen der Array-Indizes und Ausgeben der Quadrate
for I := 0 to 9 do
WriteLn('Quadratwert: ', MyArray[I]);
// 3. Low/High holen automatisch die Array-Grenzen, keine fest eingetragenen 0 und 9, besser erweiterbar
for I := Low(MyArray) to High(MyArray) do
WriteLn('Quadratwert: ', MyArray[I]);
// 4. while-Schleife: Zuerst Bedingung prüfen, nur bei wahrer Bedingung Schleifenkörper ausführen
I := 0;
while I < 10 do
begin
WriteLn('Quadratwert: ', MyArray[I]);
I := I + 1; // Äquivalente Schreibweisen: I+=1 / Inc(I)
end;
// 5. repeat-until-Schleife: Schleifenkörper einmal ausführen, am Ende die Abbruchbedingung prüfen
I := 0;
repeat
WriteLn('Quadratwert: ', MyArray[I]);
Inc(I); // Zähler erhöhen
until I = 10;
// 6. for-in-Durchlauf: Direkt Elementwerte auslesen, ohne Indexmanipulation
for I in MyArray do
WriteLn('Quadratwert: ', I);
end.Code-Sprache: PHP (php)
Unten steht der Code ohne alle Kommentare
{$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('Quadratwert: ', MyArray[I]);
for I := Low(MyArray) to High(MyArray) do
WriteLn('Quadratwert: ', MyArray[I]);
I := 0;
while I < 10 do
begin
WriteLn('Quadratwert: ', MyArray[I]);
I := I + 1;
end;
I := 0;
repeat
WriteLn('Quadratwert: ', MyArray[I]);
Inc(I);
until I = 10;
for I in MyArray do
WriteLn('Quadratwert: ', I);
end.Code-Sprache: PHP (php)
Im Folgenden analysieren wir den Code jeder Schleife Schritt für Schritt
for-Schleife
Werte einem Array mit einer for-Schleife zuweisen
{$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-Sprache: PHP (php)
Dieser Code gliedert sich in drei Bereiche: Oben stehen Präkompilieranweisungen, im var-Bereich werden Variablen deklariert (ein Array, eine Ganzzahl), der Hauptausführungsblock zwischen begin und end. enthält eine for-Schleife, die nacheinander Werte von 0 bis 9 an I übergibt und per Index das Array befüllt.
Wir belegen die zehn Array-Elemente MyArray[0] bis MyArray[9]. Das Sternchen * ist der Multiplikationsoperator.
MyArray[0] := 0 * 0;
MyArray[1] := 1 * 1;
…
MyArray[9] := 9 * 9;
Fügen Sie unter der ersten for-Schleife eine weitere for-Schleife hinzu, um alle im Array gespeicherten Elemente auszulesen.

Nach Kompilieren und Ausführen werden alle gespeicherten Werte ausgegeben

Alle Ausgaben sind die Quadrate von 0 bis 9 und stimmen mit unseren vorherigen Erwartungen überein.
Wenn Sie den Indexbereich eines Arrays nicht kennen, nutzen Sie eingebaute Funktionen, um die untere und obere Grenze abzufragen.

Die obige Funktion Low(Arrayname) liefert den kleinsten Indexwert eines Arrays
Low(Typ/Variable): Ermittelt den Minimalwert / untere Grenze von Ordinaltypen, Arrays, MengenHigh(Typ/Variable): Ermittelt den Maximalwert / obere Grenze von Ordinaltypen, Arrays, Mengen
while- und repeat-Schleifen

Innerhalb des mit begin end; umschlossenen while-Schleifenkörpers wird die Variable I am Ende des Blocks um 1 erhöht. Nach der Erhöhung springt der Programmablauf zurück zu while I < 10 do für eine neue Bedingungsprüfung. Ist die Bedingung wahr, läuft der Schleifenkörper erneut, I steigt wieder um 1, die Prüfung wiederholt sich. Der Vorgang endet erst, wenn I < 10 unwahr wird – also sobald I den Wert 10 erreicht.


Wesentliche Unterschiede zwischen while und repeat-until
- Entgegengesetzte Prüflogik
while Bedingung do: Bedingung wahr → Schleife fortsetzen; Bedingung unwahr → Schleife verlassenrepeat ... until Bedingung: Bedingung wahr → Schleife verlassen; Bedingung unwahr → Schleife fortsetzen
- Garantierte Mindestausführungen unterschiedlich
- while: Ist die Anfangsbedingung unwahr, wird der Schleifenkörper gar nicht ausgeführt
- repeat-until: Unabhängig von der Bedingung läuft der Schleifenkörper mindestens einmal
Wenn Sie Sprachen wie C, C++ oder Java gelernt haben, verstehen Sie es sofort: repeat-until funktioniert genau wie do-while. Zuerst läuft der Schleifeninhalt einmal, dann wird die Bedingung nach until geprüft. Ist sie unwahr, wiederholt sich die Schleife.
Bei repeat-until brauchen Sie kein begin und end, repeat bis until bildet von Haus aus einen einzigen Codeblock. Sie können begin end optional ergänzen, es ist aber nicht empfehlenswert.
Der wörtliche Sinn von repeat-until lautet „Wiederhole … bis“, die Funktionsweise ist am Begriff selbst leicht abzulesen.

Beim Durchlaufen werden nacheinander alle Werte aus MyArray an I zugewiesen, sodass Sie I direkt im Schleifenkörper bearbeiten können. Es ist nicht nötig, den Index manuell zu erhöhen – Sie brauchen sogar gar keinen Index, bis das gesamte Array durchlaufen ist.
Erläuterung der klassischen for-Schleife (for I := ... to/downto)
- Ähnlich der C-for-Schleife, aber restriktiver: Nur zusammenhängende Ordinalwerte (Ganzzahlen, Enums) können durchlaufen werden;
- Rückwärtsdurchlauf mit downto unterstützt:
for I := 9 downto 0 do; - Die Grenzen Low(xx) / High(xx) werden nur einmal beim Start der Schleife berechnet – hohe Laufzeiteffizienz;
- Nach regulärem Schleifenende ist der Wert von I undefiniert, der Compiler gibt eine Warnung aus. Bei vorzeitigem Abbruch mit Break oder Exit behält I seinen aktuellen Wert.
for-in-Durchlauf (moderner foreach-Stil)
Kann vier Datentypen durchlaufen, ohne manuell Indizes zu verwalten:
- Arrays: Direkt jeden Elementwert auslesen (in vorherigen Beispielen demonstriert)
- Enumerationstypen
{$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-Sprache: PHP (php)

- Mengentypen
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
type
// Enumerationstyp definieren
TAnimalKind = (Duck, Cat, Dog);
// Auf Enum basierenden Mengentyp erstellen
TAnimals = set of TAnimalKind;
var
Animals: TAnimals;
AK: TAnimalKind;
begin
// Zwei Enum-Werte in die Menge schreiben: Duck und Cat
Animals := [Duck, Cat];
// Mit for-in alle vorhandenen Mitglieder der Menge durchlaufen
for AK in Animals do
begin
WriteLn('Gefundenes Tier: ', AK);
end;
end.Code-Sprache: PHP (php)

- Generische Listen (lernen wir in späteren Kapiteln)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
SysUtils, Generics.Collections; // Unit für generische Container einbinden
type
TMyClass = class // Eigene Klasse zum Speichern von Zahl und Quadrat
I, Square: Integer;
end;
// Generische Objektliste instanziieren, automatische Lebenszyklusverwaltung
TMyClassList = {$ifdef FPC}specialize{$endif} TObjectList<TMyClass>;
var
List: TMyClassList;
C: TMyClass;
I: Integer;
begin
List := TMyClassList.Create(true); // true: interne Objekte beim Zerstören der Liste automatisch freigeben
try
// Objekte in Schleife erstellen und der Liste hinzufügen
for I := 0 to 9 do
begin
C := TMyClass.Create;
C.I := I;
C.Square := I * I;
List.Add(C);
end;
// Mit for-in jedes benutzerdefinierte Objekt in der Liste direkt durchlaufen
for C in List do
WriteLn('Das Quadrat von ', C.I, ' ist ', C.Square);
finally
FreeAndNil(List); // Liste sicher freigeben, Speicherlecks vermeiden
end;
end.
Code-Sprache: HTML, XML (xml)
Hinweis: Dieses Beispiel nutzt Klassen und Generika. Anfänger können es vorerst überspringen, wir erklären es detailliert im Kapitel zur objektorientierten Programmierung.