Die dritte grundlegende Kontrollstruktur sind Wiederholungen, mit denen eine Befehlsfolge mehrfach wiederholt werden kann.
Es gibt grundsätzlich zwei verschiedene Wiederholungsstrukturen:

In der Objektorientierung gibt es zusätzlich noch die foreach-Schleife, die man aber auch bei Arrays verwenden kann.

Zählschleife

Die Zählschleife ist eine Wiederholungsstruktur, bei der die Anzahl der Wiederholungen bereits im Voraus bekannt ist. Das ist das wesentliche Merkmal dieser Wiederholungsstruktur!
Eine Zählschleife könnte so aussehen:

for (int i = 0; i < 10; i++)
{
    // Zu wiederholende Anweisungen
    Console.WriteLine(i.ToString());
}
Struktogramm für eine for-Schleife

Der Schleifenkopf enthält die Anweisungen, die Wiederholungen steuern. In dem runden Klammernpaar sind drei Ausdrücke angegeben:

  1. Die Anweisung int i = 0; gibt den Typ und die Bezeichnung der Zählvariablen an und initialisiert diese mit einem Startwert; hier: 0.
  2. Die Anweisung i < 10; ist die Laufbedingung und gibt an, für welche Werte von i eine Wiederholung erfolgen soll; in diesem Fall werden die Anweisungen im nachfolgenden Anweisungsblock wiederholt, solange der Wert von i kleiner 10 ist.
  3. Die dritte Anweisung (hier: i++) gibt an, wie sich die Zählvariable nach jeder Wiederholung ändern soll. In diesem Beispiel wird die Zählvariable i nach jeder Wiederholung inkrementiert, also um 1 erhöht.

Die Verarbeitung einer Zählschleife erfolgt nach diesem Prinzip:

  1. Zuerst wird die angegebene Zählvariable erzeugt und mit dem Startwert (hier: 0) initialisiert.
  2. Dann wird überprüft, ob die Laufbedingung (hier: i < 10) den Wahrheitswert true liefert; falls ja wird der nachfolgende Anweisungsblock einmal ausgeführt. Falls nein, endet die Verarbeitung und die Programmausführung wird hinter dem Anweisungsblock fortgesetzt.
  3. Nach Ausführung des Anweisungsblocks wird die Zählvariable gemäß dem dritten Ausdruck (hier: i++) verändert. Anschließend wird die Verarbeitung mit dem Schritt 2 (Prüfung der Laufbedingung) fortgesetzt.

Ein absolutes NoGo bei der Zählschleife ist die Veränderung der Zählvariablen innerhalb des Anweisungsblocks! Die Zählvariable wird zwar fast immer innerhalb des Anweisungsblocks verwendet, aber sie wird nie durch eine Zuweisungsoperation modifiziert!

Noch ein Wort zur Zählvariable:
Sehr häufig wird für die Zählvariable der Bezeichner i verwendet. Der Datentyp für die Zählvariable ist (fast immer) ein Ganzzahltyp wie int. In der Programmiersprache FORTRAN waren Variablen deren Bezeichner mit i, j, k, l, m und n begonnen haben, grundsätzlich Ganzzahltypen (implizite Variablendeklaration).

Natürlich können trotzdem andere Bezeichner für die Zählvariable verwendet werden und dies ist häufig im Hinblick auf eine bessere Lesbarkeit von Programmen sinnvoll! Wenn die Zählvariable im Schleifenkopf deklariert wird, ist sie auch nur im Rahmen des Anweisungsblocks existent und zugreifbar! Daher würde es in dem nachfolgenden Programm in Zeile 6 zu einem Fehler kommen, da die Zählvariable hinter dem Anweisungsblock der for-Schleife nicht mehr existiert.

Console.WriteLine("Countdown startet!");
for (int i = 10; i >= 0; i--)
{
    Console.WriteLine(i.ToString());
}
Console.WriteLine("BOOOOM\nDer Wert von i ist jetzt {0}", i.ToString());

Wird die Zählvariable jedoch bereits vor der for-Schleife deklariert und bekommt im Schleifenkopf lediglich den Startwert zugewiesen, ist diese natürlich weiterhin verfügbar! Deshalb würde es in dem nachfolgenden Programm zu keinem Fehler kommen! Aber in der Regel ist dies nicht erforderlich!

int i;
Console.WriteLine("Countdown startet!");
for (i = 10; i >= 0; i--)
{
    Console.WriteLine(i.ToString());
}
Console.WriteLine("BOOOOM\nDer Wert von i ist jetzt {0}", i.ToString());

Offene Schleife

Offene Schleifen werden immer dann verwendet, wenn die Anzahl der Wiederholungen im Voraus nicht bekannt ist! Offene Schleifen verwenden nur eine Laufbedingung, d.h. eine Bedingung wie bei einer Entscheidungsstruktur, die als boolscher Ausdruck lediglich false oder true liefert. Liefert diese Laufbedingung den Wahrheitswert true, wird der Anweisungsblock erneut ausgeführt; ist der Wahrheitswert hingegen false, wird die Programmausführung hinter dem Anweisungsblock fortgesetzt. Die Laufbedingung kann wie auch bei Entscheidungen aus mehreren Teilbedingungen bestehen, die mittels Logikoperatoren verknüpft sind.

Es gibt zwei Arten einer Offenen Schleife:

  • while-Schleife oder auch abweisende Schleife bzw. kopfgesteuerte Schleife genannt
  • do…while-Schleife oder auch nicht abweisende Schleife bzw. fußgesteuerte Schleife genant
while (Bedingung)
{
    // Anweisungen, die
    // wiederholt werden sollen
}
do
{
    // Anweisungen, die
    // wiederholt werden sollen
    // mindestens einmal
}
while (Bedingung)

Der Unterschied zwischen diesen beiden Schleifen liegt eben darin, dass der Anweisungsblock einer while– Schleife u.U. überhaupt nicht ausgeführt wird (wenn die Bedingung zu Beginn den Wahrheitswert false liefert), während der Anweisungsblock bei einer do…while-Schleife mindestens einmal ausgeführt; in der Regel aber mehrfach, bis die Bedingung eben den Wahrheitswert false liefert.

Im Unterschied zur for-Schleife, bei der die Zählvariable in dem Anweisungsblock nie geändert werden soll, müssen bei diesen beiden Schleifen sehr wohl die Variablen, die in der Bedingung enthalten sind, im Anweisungsblock geändert werden!

Ist dies nicht der Fall, entsteht eine Endlosschleife!

Offene Schleifen können immer eine Zählschleife ersetzen und sind somit universeller verwendbar; umgekehrt nicht! Allerdings sind Zählschleifen performanter und sollten daher immer verwendet werden, wenn es die Situation erlaubt; d.h. wenn die Anzahl der Wiederholungen im Voraus bekannt ist.

In vielen Fällen ist es unerheblich, ob man eine while-Schleife oder eine do…while-Schleife einsetzt. Wenn aber klar ist, dass der Anweisungsblock mindestens einmal durchlaufen werden soll, muss man die do…while-Schleife verwenden. Nachfolgend zwei Beispiele:

Console.Write("Anfangskapital > ");
double anfangskapital = Convert.ToDouble(Console.ReadLine());
Console.Write("Zinssatz [%] > ");
double zinssatz = Convert.ToDouble(Console.ReadLine());
double kapital = anfangskapital;
int laufzeitjahre = 0;
while (kapital < anfangskapital *2)
{
    double zinsen = kapital * zinssatz /100;
    kapital += zinsen;
    laufzeitjahre++;
}
Console.WriteLine("Endkapital={0} nach {1} Jahren",
                    kapital.ToString(),
                    laufzeitjahre.ToString());
Console.WriteLine("Menue\n=====");
Console.WriteLine("1 Spiel starten");
Console.WriteLine("2 Spieler bearbeiten");
Console.WriteLine("3 Spiel beenden");

int auswahl = 0;
do
{
    Console.Write("Ihre Auswahl > ");
    auswahl = Convert.ToInt32(Console.ReadLine());
}
while (auswahl < 1 || auswahl > 3);

Im links dargestellten Programm wird berechnet, wie lange es dauert, bis sich ein bestimmtes Anfangskapital bei einem bestimmten Zinssatz verdoppelt hat. Dies kann nicht mit einer Zählschleife gemacht werden, da sich augenscheinlich die Verdopplung aufgrund des Zinssatzes ergibt.

Im rechts dargestellten Programm wird ein Menü angezeigt und der Benutzer soll einen der drei Menüpunkte auswählen.
Die Auswahl erfolgt in einer fußgesteuerten Schleife, da der Benutzer ja mindestens einmal eine Eingabe machen muss. Die Eingabe wird solange wiederholt, bis der eingelesene Wert nicht kleiner 1 bzw. nicht größer 3 ist.
Auch hier kann keine Zählschleife verwendet werden, da ja nicht bestimmbar ist, wie oft der Benutzer (absichtlich oder unabsichtlich 😉 ) eine falsche Eingabe macht.

Mein Arbeitsblatt zum Thema:

Zurück zu Entscheidung/Auswahl

Nach oben zu Strukturierte Programmierung