For-Schleife

Programmanweisung
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 8. März 2006 um 01:45 Uhr durch RobotQuistnix (Diskussion | Beiträge) (Bot: Ergänze: it). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Viele Programmiersprachen definieren eine For-Schleife als eine Kontrollstruktur, mit der man eine Gruppe von Anweisungen (Block) mit einer bestimmten Anzahl von Wiederholungen ausführen kann.

Es gibt im Wesentlichen drei Arten von For-Schleifen: Algol-artige, C-artige und eine Foreach-Schleife.

Die Algol-artige For-Schleife

Diese Art der For-Schleife dient in erster Linie dazu, eine Anweisung wiederholt auszuführen. Sie hat folgende Eigenschaften:

  • Die Anzahl der Wiederholungen steht schon beim Eintritt in die Schleife fest.
  • Es gibt eine sogenannte Schleifenvariable, die am Anfang auf den Startwert gesetzt wird und dann jeweils um die Schrittweite verändet wird, bis der Zielwert erreicht ist. Die Schleifenvariable, der Startwert, die Schrittweite und der Endwert müssen numerisch sein.
  • Bei jedem Schritt wird die Anweisung ausgeführt.
  • In einigen Programmiersprachen sind Start- und Endwert auf ganze Zahlen beschränkt.
  • In Pascal ist die Schrittweite auf 1 (Schlüsselwort to) oder   (downto) beschränkt.
  • In einigen anderen Programmiersprachen können der Startwert, der Endwert und die Schrittweite auch gebrochene Zahlen sein.

Die Definition, wie eine For-Schleife auszusehen hat (Syntax), ist von Programmiersprache zu Programmiersprache verschieden. Die Elemente, aus denen eine For-Schleife besteht, sind aber fast immer dieselben. Auch die Bedeutung einer For-Schleife (Semantik), also die Art, wie sie ausgeführt wird, ist von Sprache zu Sprache verschieden. Hier einige Beispiele:

Pascal

Eine For-Schleife hat die Form:

for Variable := Startwert [to|downto] Endwert do Anweisung

Die Bedeutung der For-Schleife mit to ist im PASCAL User Manual and Report (ISBN 3-540-06950-X) als äquivalent zu den folgenden Anweisungen definiert.

if Startwert <= Endwert then
begin
  Variable := Startwert;  Anweisung;
  Variable := succ(Variable);  Anweisung;
  ...;
  Variable := Endwert;  Anweisung;
end

Die Ausdrücke Startwert und Endwert werden dabei nur einmal ausgewertet. Für die For-Schleife mit downto muss lediglich das <= in >= und das succ in pred geändert werden.

Aufgrund dieser Definition könnte ein findiger Programmierer jetzt auf die Idee kommen, den Wert der Variable innerhalb der Anweisung zu verändern. Dem schiebt die Sprachbeschreibung von Pascal jedoch einen Riegel vor, denn da steht: „The control variable, the initial value, and the final value must [...] not be altered by the for statement“. Also dürfen auch Startwert und Endwert während der ganzen For-Schleife nicht verändert werden. Viele Programmierer machen das aber trotzdem und erzeugen so Programme, die im strengen Sinne keine Pascal-Programme sind, da sie sich nicht an die Sprachdefinition halten.

Beispiel

program Fakultaetsberechnung;
var
  Zaehler, Fakultaet: Integer;
begin
  Fakultaet := 1;
  for Zaehler := 1 to 5 do
    Fakultaet := Fakultaet * Zaehler;
  writeln(Fakultaet);
end.

Modula-3

Eine For-Schleife hat die Form:

FOR Variable := Startwert TO Endwert [BY Schrittweite] DO Anweisungen END

Die Bedeutung ist die gleiche wie der folgende Code, wobei i, ew und sw Variablen sind, vom Programm aus nicht sichtbar sind.

VAR i := ORD(Startwert); ew := Endwert; sw := Schrittweite;
BEGIN
 IF sw >= 0 THEN
    WHILE i <= ew DO
      WITH Variable = VAL(i, T) DO S; END;
      INC(i, sw);
    END
  ELSE
    WHILE i >= ew DO
      WITH Variable = VAL(i, T) DO S; END;
      DEC(i, sw);
    END
  END
END

Die Unterschiede zur For-Schleife von Pascal sind, dass die Variable in Modula-3 automatisch deklariert wird und dass die Schrittweite nicht auf 1 und   beschränkt ist. Außerdem ist die Variable schreibgeschützt, das heißt, sie kann auch durch Tricksereien nicht verändert werden.

Der Code, durch den diese For-Schleife definiert ist, ist allerdings fehleranfällig, falls der Endwert die größtmögliche Zahl ist. Dadurch kann es entweder zu einer Endlosschleife kommen (auf Rechnern, auf denen die größtmögliche Zahl + 1 die kleinstmögliche ergibt) oder zu einem unerwarteten Programmabbruch. Die Autoren von Modula-3 waren sich dessen bewusst, deshalb steht im Modula-3-Handbuch auch:

If the upper bound of the loop is LAST(INTEGER), it should be rewritten as a WHILE loop to avoid overflow.

Die C-artige For-Schleife

In C-artigen Programmiersprachen hat eine For-Schleife die Form:

for (Initialisierung; Test; Fortsetzung) Anweisung

Und so wird sie ausgeführt (nach ISO/IEC 9899:1999):

  1. Der Ausdruck Initialisierung wird ausgewertet. Falls es sich dabei um eine Deklaration handelt, sind die darin definierten Variablen nur innerhalb der For-Schleife gültig.
  2. Der Ausdruck Test wird als boolescher Ausdruck ausgewertet. Falls der Wert false ist, wird die For-Schleife beendet.
  3. Die Anweisung Anweisung wird ausgeführt.
  4. Der Ausdruck Fortsetzung (meistens eine Anweisung) wird ausgewertet.
  5. Es geht mit 2. weiter.

Die C-artige For-Schleife ist vielseitiger verwendbar als die Algol-artige. So können zum Beispiel auch verkettete Listen bearbeitet werden. Beispiel:

struct Liste {
    struct Liste *next;
    int element;
};

[...]
for (p = liste; p != NULL; p = p->next) {
    printf("%d\n", p->element);
}
[...]

Sie wird aber sehr häufig auch in der Form der Algol-artigen For-Schleife verwendet. Beispiel:

for (i = 0; i < length; i++) {
    if (i * i < n) {
        ...
    }
}

Im Gegensatz zur Algol-Variante wird hier die Schleifenvariable dreimal statt nur einmal erwähnt. Das kann beim nachträglichen Ändern von Programmcode leicht dazu führen, dass die Variable an nur zwei der drei Stellen geändert wird. Wenn bei einer eventuellen Änderung das < durch ein <= ersetzt wird, verändert das die Bedeutung des Programms, ohne im Quelltext groß aufzufallen. Dadurch können sich leicht Fehler einschleichen.

Die Foreach-Schleife

Einige Programmiersprachen (Perl, Python) bieten ein Konstrukt an, um einer Variable nacheinander alle Elemente einer Liste zuzuweisen.

Perl

Eine Foreach-Schleife hat die Form:

foreach Variable (Werte) { Anweisungen }

Beispiel

foreach my $name ("Anna", "Heinz", "Sebastian") {
    print("Hallo, $name\n");
}

Weitere Beispiele

Berechnung der Fakultät

In Basic (hier: Visual Basic)

Option explicit
Dim Fakultaet as Long
Dim Zaehler as Integer

Fakultaet = 1
For Zaehler = 1 to 5 Step 1
       Fakultaet = Fakultaet * Zaehler
Next

Print Fakultaet
#include <stdio.h> 

int main(void)
{
      int Zaehler;
      int Fakultaet = 1;

      for (Zaehler = 1; Zaehler <= 5; Zaehler++)
             Fakultaet *= Zaehler;

      printf("%d\n", Fakultaet);

      return 0;
}

In C99 oder C++

#include <stdio.h> 

int main(void)
{
      int Fakultaet = 1;

      for (int Zaehler = 1; Zaehler <= 5; ++Zaehler)
             Fakultaet *= Zaehler;

      printf("%d\n", Fakultaet);
 }
faktorial _ 1.
1 to: 5 do: [ :i | faktorial _ faktorial * i].
Transcript show: faktorial printString

In Perl

use strict;
my $fakultaet = 1;
for (my $zaehler = 1; $zaehler <= 5; $zaehler++) {
    $fakultaet *= $zaehler;
}
print "Fakultät = $fakultaet\n";

Siehe auch