Schleife (Programmierung)
Eine Schleife ist eine Kontrollstruktur in Programmiersprachen. Sie wiederholt einen Teil des Codes – den so genannten Schleifenrumpf oder Schleifenkörper – so lange, bis eine Abbruchbedingung eintritt. Schleifen, die ihre Abbruchbedingung niemals erreichen, und Schleifen, die keine Abbruchbedingungen haben, sind Endlosschleifen.
Prinzipiell werden unterschieden:
- die kopfgesteuerte oder vorprüfende Schleife, bei der die Abbruchbedingung geprüft wird, bevor der Schleifenrumpf durchlaufen wird (meist mit WHILE = während eingeleitet).
- die fußgesteuerte oder nachprüfende Schleife, bei der nach dem Durchlauf des Schleifenrumpfes die Abbruchbedingung überprüft wird (meist als DO-WHILE = ausführen-während oder REPEAT-UNTIL = wiederholen-bis Konstrukt).
- die Zählschleife, eine Sonderform der kopfgesteuerten Schleife (meist als FOR = für -Schleife implementiert).
Eine Endlosschleife kann nur von außen unterbrochen werden (Reset, Interrupt, Abschalten des Gerätes, Defekt oder ähnliches).
Befehle in höheren Programmiersprachen
Hier folgen ein paar der bekanntesten Schleifen in Pseudocode. Die Verwendung in echten Programmiersprachen ist meist sehr ähnlich.
FOR Iterator:=Anfangszahl TO Endezahl STEP Schrittweite DO Schleifenrumpf.
Bei einer For-Schleife zählt der Computer von einer Anfangszahl bis zu einer Endzahl und wiederholt dabei jedesmal den Codeblock. Die aktuelle Zahl wird in eine Variable gesetzt, damit sie bei Bedarf in dem Codeblock Verwendung finden kann (details).
WHILE Logischer Ausdruck DO Schleifenrumpf.
Bei einer While-Schleife wird der Schleifenrumpf solange wiederholt, bis die logische Operation einen falschen Rückgabewert liefert. Eine logische Operation kann beispielsweise sein: (x > 4) Solange diese Bedingung wahr ist, läuft die Schleife. Wird der Inhalt der logischen Operation nicht im wiederholten Teil des Programmcodes verändert, ist diese Kontrollstruktur meist nicht die richtige, weil diese Schleife sonst kein einziges Mal durchlaufen wird oder unendlich lang läuft.
DO Schleifenrumpf WHILE Logischer Ausdruck
bzw.
REPEAT Schleifenrumpf UNTIL Logischer Ausdruck
Funktioniert genau so wie die While-Schleife, allerdings wird die Abbruchbedingung erst nach den Durchlauf des eingeschlossenen Programmcodes überprüft.
Befehle in Assembler
Assemblercode verfügt normalerweise nicht über die aus höheren Programmiersprachen bekannten for/while/repeat Konstrukte. Da aber auch hier Schleifen eingesetzt werden müssen (Verzögerung durch aktives Warten (s.u.), serielles adressiertes Verarbeiten von Daten), stehen einfache Sprungbefehle für unbedingte und bedingte Springe zur Verfügung.
Letztere entscheiden anhand eines Statusflags der CPU (z.B. Zero-Flag), ob gesprungen werden muss. Trifft die Voraussetzung nicht zu, so wird der Programmcounter (PC) einfach um eins erhöht. Es wird dann also als nächstes der Befehl nach dem bedingten Sprungbefehl ausgeführt.
Beispiel für Code für einen AVR-Microcontroller, der unter Verwendung einer Schleife um insgesamt 5000 Takte durch aktives Warten verzögert:
; delaying 4998 clocks ldi R0, $07 Label0: ldi R1, $ed Label1: dec R1 ; Vermindert Inhalt in R1 um 1 brne Label1 ; Sprung nur, wenn R1 nun nicht 0 ist. dec R0 ; alternativ gehts hier weiter brne Label0 ; delaying 2 clocks nop nop
Implementierung mit Sprungbefehlen
Früher wurden auch in Hochsprachen-Programmen häufig unbedingte Sprünge (Goto-Befehle) verwendet. Sprachen, die Sprunganweisungen verwenden, ermöglichen das Einfügen einer Marke (engl. Label). Eine solche Marke kann dann als Ziel einer Goto-Anweisung dienen.
Heutzutage wird jedoch von der Verwendung von Goto-Sprüngen abgeraten, da durch diese der berüchtigte "Spagetticode" entsteht.
Implementation einer For-Schleife mit Goto-Befehlen
Es gibt mehrere Alternativen, For-Schleifen mit Hilfe einfacherer Befehle zu implementieren. Im Normalfall verhalten sich diese Alternativen gleich, aber in einigen speziellen Situationen gibt es Unterschiede. Beispiele für spezielle Situationen sind:
* Die Schrittweite ist 0 (nicht in allen Varianten der For-Schleife möglich). * Der Startwert oder der Endwert sind die kleinst- oder größtmögliche darstellbare Zahl.
Eine ausführlichere Darstellung der Varianten befindet sich im Artikel For-Schleife.
Ersatz des While-Do-Befehls durch einen Goto-Befehl
WHILE Logischer Ausdruck DO Befehlssequenz.
entspricht:
Marke1: IF NOT Logischer Ausdruck GOTO Marke2 (bedingter Vorwärtssprung) Befehlssequenz GOTO Marke1 (Rückwärtssprung) Marke2:
Wieder wird die Befehlssequenz keinmal durchlaufen, wenn der logische Ausdruck schon zu Beginn falsch ist.
Ersatz des Do-While-Befehls durch einen Goto-Befehl
DO Befehlssequenz WHILE Logischer Ausdruck
entspricht:
Marke1: Befehlssequenz IF Logischer Ausdruck GOTO Marke1 (bedingter Rückwärtssprung)
Ersatz des Repeat-Until-Befehls durch einen Goto-Befehl
REPEAT Befehlssequenz UNTIL Logischer Ausdruck
entspricht:
Marke1: Befehlssequenz IF NOT Logischer Ausdruck GOTO Marke1 (bedingter Rückwärtssprung)