For-Schleife

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
Struktogramm einer For-Schleife

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

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

Numerische Schleife

[Bearbeiten | Quelltext bearbeiten]
Monitor eines CBM 3016 mit Commodore-BASIC-Programm, das in Zeile 100 PEEK und POKE in einer FOR-Schleife verwendet.

Die Anzahl der Wiederholungen steht schon beim Eintritt in die Schleife fest. Es gibt eine Schleifenvariable, die am Anfang auf den Startwert gesetzt wird und dann jeweils um die Schrittweite verändert wird, bis der Zielwert erreicht ist. Die Schleifenvariable, der Startwert, die Schrittweite und der Endwert müssen numerisch sein. Diese Form der Schleife ist daher auch unter dem Begriff Zählschleife bekannt.

In den meisten Programmiersprachen sind Start-, Endwert und Schrittweite auf ganze Zahlen beschränkt. Bei manchen Sprachen ist die Schrittweite auf 1 (bzw. −1 mit downto statt to) beschränkt.

Die Grundstruktur dieser For-Schleifen ist folgende (hier am Beispiel BASIC):

For Zähler = Start To Ende Step n
    ' zu
    ' wiederholende
    ' Anweisungen
Next

Ausdrucksorientierte Schleife

[Bearbeiten | Quelltext bearbeiten]

Die ausdrucksorientierte Schleife erlaubt es auch mit nicht numerischen Schleifenvariablen zu arbeiten. So können zum Beispiel auch verkettete Listen bearbeitet werden.

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.

Beispiel für Verwendung als nichtnumerische Schleife:

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

for (p = liste; p != NULL; p = p->next) {
    
}

Beispiel für Verwendung als numerische Schleife:

for (i = 0; i < length; i++) {
    
}

Verschachtelte For-Schleifen

[Bearbeiten | Quelltext bearbeiten]

Innerhalb einer For-Schleife können sich eine oder mehrere weitere For-Schleifen befinden. Das sind verschachtelte For-Schleifen.

Das Sortierverfahren Bubblesort verwendet zwei verschachtelte For-Schleifen. In der inneren Schleife werden benachbarte Elemente vertauscht.

public void Bubblesort(object[] elements)
{
    for (int i = elements.Length - 1; i > 0; i--)
    {
        for (int j = 0; j < i; j++)
        {
            object element1 = elements[j];
            object element2 = elements[j + 1];
            if (element1 > element2)
            {
                elements[j] = element2;
                elements[j + 1] = element1;
            }
        }
    }
}

Die folgende Methode berechnet die Binomialkoeffizienten im Pascalschen Dreieck und gibt ein zweidimensionales Array zurück:

public int[][] Binomial(int n)
{
    int[][] binomials = new int[n][];
    binomials[0] = new int[1];
    binomials[0][0] = 1;
    for (int i = 1; i < n; i++)
    {
        binomials[i] = new int[i + 1];
        for (int j = 0; j <= i; j++)
        {
            int left = 0;
            if (j > 0)
            {
                left = binomials[i - 1][j - 1];
            }
            int right = 0;
            if (j < i)
            {
                right = binomials[i - 1][j];
            }
            binomials[i][j] = left + right;
        }
    }
    return binomials;
}

Foreach-Schleife

[Bearbeiten | Quelltext bearbeiten]

Einige Programmiersprachen (zum Beispiel C++, C#, Java, Perl, Python, PHP, Ruby) bieten ein Konstrukt an, um einer Variable nacheinander alle Elemente einer Liste zuzuweisen. Dieses Konstrukt wird entsprechend seinem üblichen Schlüsselwort meist Foreach-Schleife genannt. Je nach Programmiersprache unterscheiden sich Notation und Schlüsselwort jedoch. So wird die Foreach-Schleife in Object Pascal und JavaScript als For-In-Schleife bezeichnet. In JavaScript wird der Variable entgegen der oben genannten Beschreibung nur der Index bzw. Schlüssel zugewiesen und nicht das Element selbst, denn für letzteres gibt es die For-Of-Schleife.

Ab der Version C++11 gibt es in C++ die bereichsbasierte For-Schleife (engl. range-based for).[1] Diese vereinfacht das Iterieren über beliebige Container und andere Objekte, für die die Funktionen std::begin und std::end überladen worden sind, z. B. alle Container der Standardbibliothek, aber auch über eingebaute Arrays (C-style arrays) oder benutzerdefinierte Containerdatentypen:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec(5); // Initialisiere vec mit 5 Zellen

    // range-basierte for-Schleife über Initialisiererliste (std::initializer_list) und Zuweisung an die Vektorelemente
    for (auto i: {1, 2, 3, 4, 5}) {
        vec[i-1] = i;
    }

    // range-basierte for-Schleife über Vektor
    for (auto i: vec) {
        std::cout << i << " ";
    }
}

[2]

Das hierbei benutzte Schlüsselwort auto bringt den Compiler dazu, automatisch den benötigten Typ zu nutzen (wäre bei beiden Schleifen int).

In C# hat die foreach-Schleife folgende Form:

foreach (datatype element in enumerable)
{
    
}

Im folgenden Beispiel durchläuft die foreach-Schleife alle Länder der generischen Liste und gibt alle Länder aus, deren Name auf "land" endet:

// Generische Liste der Länder
List<string> countries = new List<string>();

// Liste füllen
countries.Add("Germany");
countries.Add("Austria");
countries.Add("Switzerland");
countries.Add("France");
countries.Add("Poland");
countries.Add("United States");

// Die foreach-Schleife durchläuft der Reihe nach alle Elemente der Liste
foreach (string country in countries)
{
    if (country.EndsWith("land"))
    {
        Console.WriteLine(country);
    }
}

Eine Foreach-Schleife in Ada hat die Form:

for Variable_1 in Variable_2'Range loop
    Anweisungen
end loop;

Beispiel:

A : array (3..5) of Integer := (5, 9, 10);
for I in A'Range loop
    Put (A(I));
end loop;

Eine For oder Foreach-Schleife (beide Schlüsselworte sind synonym in Perl) hat die Form:

foreach Variable (Werte) { Anweisungen }

Beispiel:

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

$name ist die Variable, die nacheinander die Werte in den Klammern zugewiesen bekommt.

Enthält der Schleifenblock nur einen Befehl, kann auch die nachgestellte Form eingesetzt werden, welche allerdings keine selbstbenannte Laufvariable erlaubt:

say "Hallo, $_." for qw/Anna Heinz Sebastian/;

Eine Verwendung wie in C ist ebenfalls möglich:

for ($i = 0; $i < $length; $i++)
{
    
}

Eine Foreach-Schleife in PHP hat die Form:

foreach (Array as Schluessel => Wert)
{
    
}

Schluessel und Wert wird in jedem Schleifendurchlauf ein Schlüssel-Wert-Paar aus dem Array zugewiesen. PHP-Arrays unterscheiden sich zu vielen anderen Programmiersprachen dadurch, dass jeder Eintrag ein Schlüssel-Wert-Paar sein kann, nicht nur ein einfacher Wert.

Im Gegensatz zu Perl ist die Syntax nicht an der mathematischen Lesart angelehnt, so dass es komisch klingt, wenn man den Code vorliest. Das kann insbesondere bei Programmieranfängern oder Umsteigern zu Problemen führen. In den meisten anderen Programmiersprachen folgt nämlich auf das Schlüsselwort foreach der Name der Variablen, die nacheinander die verschiedenen Werte annimmt.

Beispiel:

<?php
$namen = array (
    "Albert" => "Einstein",
    "Rasmus" => "Lerdorf",
    "Stephen William" => "Hawking"
);

foreach ($namen as $vorname => $nachname)
{
    print("Hallo, $vorname $nachname\n");
}
?>

Historisches: Die Für-Schleife von „Superplan“

[Bearbeiten | Quelltext bearbeiten]

Heinz Rutishauser entwickelte von 1949 bis 1951 die einfache algebraische Programmiersprache „Superplan“. Rutishauser kannte Konrad Zuses Arbeit über Programmiersprachen, d. h. Zuses Plankalkül und wählte den Namen in Anlehnung an Zuses Bezeichnung „Rechenplan“ für ein einzelnes Programm.
Rutishausers einfache Sprache hatte nur eine Kontrollstruktur: die Für-Anweisung bzw. Für-Schleife.

Für i=2(1)n:  + 3 = 

bedeutet z. B., dass in einem Array a zu allen (d. h. es wird mit der Schrittweite 1 weitergezählt) Elementen von Index Startwert 2 ausgehend bis zu Index Zielwert n eine 3 hinzuaddiert wird.

Einzelnachweise

[Bearbeiten | Quelltext bearbeiten]
  1. research.att.com (Memento vom 11. Mai 2011 im Internet Archive)
  2. cppreference.com Initialisiererlisten