6. Anweisungen
 
zurück
6.5 Loop-Anweisung(Schleifen)


Während mit der If- bzw. der Case-Anweisung definiert wird, ob und unter welchen Bedingungen eine Anweisungsfolge zur Ausführung kommen soll, legt man mit einer Loop-Anweisung (loop_statement <BNF>) fest, wie oft eine gegebene Anweisungsfolge aus-geführt werden soll. Solche wiederholt auszuführenden Anweisungsfolgen werden auch Schleifen genannt. Sie lassen sich durch eine Exit-Anweisung beenden.

Folgende Arten von Schleifen können spezifiziert werden, wobei für alle Arten optional ein Schleifenname definiert werden kann.


1. Endlos-Schleife

Schleife ohne Wiederholungsvorschrift

[SCHLEIFENNAME:]
loop
   -- Anweisungsfolge;
end loop [SCHLEIFENNAME];


Die Zahl der Schleifendurchläufe ist unbegrenzt.

Die Anweisungsfolge wird immer wieder zur Ausführung gebracht, bis das umgebende Programm terminiert oder, falls eine Exit-Anweisung innerhalb der Schleife ist, diese ausgeführt wird.

Endlosschleifen werden häufig in Ada-Prozessen eingesetzt, um kontinuierlich Leistungen zu erbringen (typisch für Serverprozesse). Zudem erspart sich der Programmierer oft komplizierte Schleifenvor- und Schleifennachbedingungen durch die freie Positionierung der Exit-Anweisung.

loop
   Put(Integer'Image(Nr) & ". Zahl : ");
   Get(Zahl);
   exit when Zahl = 0;
   Summe := Summe + Zahl;
   Nr := Nr + 1;
end loop;


2. Die konditionierte Schleife Schleife mit einer konditionierten Wiederholungsvorschrift

[SCHLEIFENNAME:]
while BEDINGUNG loop
    -- Anweisungsfolge;
end loop [SCHLEIFENNNAME];


Die Zahl der Schleifendurchläufe wird als begrenzt erwartet, ist aber nicht von vornherein bekannt.

Die Anweisungsfolge kommt zur Ausführung, solange die Bedingung nach "while" "True" ergibt. Diese Bedingung wird unmittelbar vor Ausführung der Anweisungsfolge ausgewertet.

Ist die Bedingung "False", wird die Ausführung der while-Schleife beendet, ohne daß die Anweisungsfolge noch einmal durchlaufen wird.

In dem folgenden Beispiel wird in der While-Schleife jeweils ein Datensatz gelesen. Sobald das Ende der Datei erreicht ist, wird die Ausführung der while-Schleife sofort beendet.

while not End_of_File (Datei) loop
    Read (Datei, Satz);
    -- ...
end loop;


3. Die Zählschleife Schleife mit einer zählbaren Wiederholungsvorschrift

[SCHLEIFENNAME:]
for ZAEHLVARIABLE in WERTEBEREICH loop
   -- Anweisungsfolge;
end loop [SCHLEIFENNNAME];


Zählschleifen sind zu bevorzugen, wenn von vornherein bekannt ist, wie oft die Schleife zu durchlaufen ist.

Die Zahl der Schleifendurchläufe ist begrenzt und von vornherein bekannt.

Wie oft die Anweisungsfolge zur Ausführung kommt, hängt von dem Wertebereich einer Zählvariablen ab (loop_parameter_specification <BNF>). Die Zählvariable durchläuft die einzelnen Werte des Wertebereiches und führt für jeden Wert die Anweisungsfolge genau einmal aus. Ist der letzte Wert durchlaufen, ist die Ausführung der For-Schleife beendet.

Die Zählvariable kann innerhalb der Schleife - z. B. als Index für eine Datenreihung - verwendet werden. Sie wird durch die For-Schleife selbst definiert, ist innerhalb der Schleife bekannt und außerhalb undefiniert. Dabei gibt es verschiedene Möglichkeiten, den Wertebereich der Zählvariablen zu spezifizieren.

Beispiel 1:

type PROZESSZUSTAENDE is (AKTIV, BEENDET, BLOCKIERT, TOT);
ZUSTANDSTABELLE: array (PROZESSZUSTAENDE) of ZAHL_PROZESSE;
...
for PROZESSINDEX in AKTIV..BLOCKIERT loop
   ZUSTANDSTABELLE(PROZESSINDEX):=0;
end loop;

Der Wertebereich der Zählvariable "PROZESSINDEX" ist als Teil des Aufzählungstyps "PROZESSZUSTAENDE" definiert. "PROZESSINDEX" durchläuft die Zustände "AKTIV" bis "BLOCKIERT". Dies sind "AKTIV", "BEENDET" und "BLOCKIERT". Für jeden dieser Zustände wird die Anweisungsfolge zwischen "loop" und "end loop" ausgeführt. Der entsprechende Eintrag in der Zustandstabelle wird auf "0" gesetzt.

Insgesamt werden also drei Einträge in der Zustandstabelle auf "0" gesetzt, d. h. die For-Schleife wird dreimal durchlaufen.

Beispiel 2:

type VENTILINDIZES is range 1..15;
VENTILE: array (VENTILINDIZES) of VENTIL;
...
for VENTILINDEX in reverse VENTILINDIZES loop
   VENTILE(VENTILINDEX).OFFEN:=FALSE;
   VENTILE(VENTILINDEX).DRUCK:=0.0;
end loop;


Der Wertebereich der Zählvariable "VENTILINDEX" entspricht dem Integertyp "VENTILINDIZES". Dieser Bereich wird rückwärts - "reverse" - durchlaufen. Die Anweisungsfolge wird zunächst für den höchsten Wert von "VENTILINDIZES" ausgeführt - es erfolgen zwei Wertzuweisungen an "VENTILE(15)". Zuletzt wird die Anweisungsfolge für den niedrigsten Wert ausgeführt - es erfolgen zwei Wertzuweisungen an "VENTILE(1)".

Für jeden Wert zwischen 15 und 1 wird die Anweisungsfolge genau einmal ausgeführt.

Beispiel 3:

type VENTILINDIZES is range 1..15;
VENTILE: array (VENTILINDIZES) of VENTIL;

for VENTILINDEX in VENTILINDIZES'SUCC(VENTILINDIZES'FIRST)..VENTILINDIZES'PRED(VENTILINDIZES'LAST) loop
   VENTILE(VENTILINDEX).OFFEN:=TRUE;
end loop;


Die Zählvariable "VENTILINDEX" durchläuft nicht den ganzen Wertebereich. Die Anweisungsfolge wird für alle Ventile vom zweiten bis einschließlich dem vorletzten ausgeführt. Der Index für das zweite Ventil wird durch "VENTILINDIZES'SUCC(VENTILINDIZES'FIRST)" spezifiziert, der Index für das vorletzte durch "VENTILINDIZES'PRED(VENTILINDIZES'LAST)".

"FIRST", "LAST", "SUCC" und "PRED" sind hierbei vordefinierte Attribute.

Beispiel 4:

for VENTILINDEX in 1..ZAEHLER_1 loop
   VENTILE(VENTILINDEX).DRUCK:=2.0;
end loop;


In diesem Beispiel wird gezeigt, daß der Wertbereich der Zählvariablen nicht statisch sein muß, sondern erst während der Laufzeit festgelegt werden kann.

Der Wertebereich der Zählvariablen "VENTILINDEX" reicht von 1 bis zu dem aktuellen Wert der Variablen "ZAEHLER_1". Mit verschiedenen Werten von "ZAEHLER_1" wird also die For-Schleife unterschiedlich oft durchlaufen.

Folgendes ist bei For-Schleifen zu beachten:
  • Die Zählvariable einer For-Schleife wird vor jedem Schleifendurchlauf aktualisiert, d. h. dekrementiert oder inkrementiert.
  • Wertzuweisungen an die Variable innerhalb eines Schleifendurchlaufs sind nicht zulässig.
  • Die Zählvariable einer For-Schleife ist außerhalb dieser Schleife nicht bekannt. Sie wird vielmehr vom Übersetzer implizit nur für diese Schleife deklariert. Um Konfusionen zu vermeiden, sollte auf die explizite Deklaration einer gleichnamigen Variablen verzichtet werden.



 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.