FOR

Aus C64-Wiki
Zur Navigation springenZur Suche springen
FOR
Syntax: FOR <Schleifenvariable>=<Startwert> TO <Endwert> [STEP <Schrittweite>]
Parameter
<Schleifenvariable>: Fließkommavariable mit dem aktuellen Zählwert
<Startwert>: Startwert der Schleifenvariable
<Endwert>: Endwert der Schleifenvariable
<Schrittweite>: Wert, der nach jedem Schleifendurchlauf zur Schleifenvariable addiert wird
Einordnung
Typ: Anweisung
Kontext: Programmstruktur
Aufgabe: Einleitung einer FOR-NEXT-Schleife
Abkürzung: fO
Token: $81 (129)
Verwandte Befehle
NEXT, STEP, TO

Anmerkung: Dieser Artikel beschreibt den BASIC-Befehl FOR unter BASIC V2 des Commodore 64.

Der BASIC-Befehl FOR ist der Anfangsbefehl in einer FOR…TO…STEP…NEXT-Konstruktion (kurz: FOR-NEXT-Schleife).

Beschreibung[Bearbeiten | Quelltext bearbeiten]

Eine FOR-NEXT-Schleife wird solange vom Startwert beginnend durchgeführt, bis der Endwert überschritten ist, aber auf jeden Fall ein Mal, unabhängig von den Parameterangaben, da die Endbedingung im NEXT-Befehl überprüft wird. Mit dem Wert der Schrittweite kann bestimmt werden, ob die Schleifenvariable erhöht oder erniedrigt wird und in welchem Maße das passieren soll. Wird der STEP-Befehl weggelassen, ist die Schrittweite immer +1. Eine FOR-NEXT-Schleife dient dazu, eine bestimmte Anzahl von gleichartigen BASIC-Befehlen wiederholend auszuführen, z. B. für gleichartige Berechnungen oder Bildschirm- sowie Druckausgaben. Der Nutzen liegt darin, dass mit weniger BASIC-Programmcode das gleiche Resultat erzielt wird.

Anstelle von

10 PRINT "AUSGABE ZEILE 1"
20 PRINT "AUSGABE ZEILE 2"
30 PRINT "AUSGABE ZEILE 3"
40 PRINT "AUSGABE ZEILE 4"
50 PRINT "AUSGABE ZEILE 5"

das Gleiche als FOR…NEXT-Schleife

10 FOR X=1 TO 5
20 PRINT "AUSGABE ZEILE";X
30 NEXT X

formuliert werden.

Als Schleifenvariable darf nur eine Fließkomma- bzw. Gleitpunktvariable angegeben werden, andernfalls erscheinen die Fehlermeldungen ?SYNTAX ERROR (im Falle von Ganzzahl- bzw. Integervariablen oder Feldvariablen) bzw. ?TYPE MISMATCH ERROR bei Zeichenkettenvariablen.
Die weiteren Parameter Startwert, Endwert und Schrittweite werden genau ein Mal, vor dem Eintritt in die Schleife ausgewertet und vermerkt. Die entsprechenden Ausdrücke müssen Fließkommazahlen im entsprechend zulässigen Wertbereich ergeben.

Den Abschluss einer FOR-NEXT-Schleife bildet der BASIC-Befehl NEXT. Beim Erreichen des BASIC-Befehls NEXT wird erst die Schleifenvariable um 1 oder um die bei STEP angegebene Schrittweite erhöht bzw. erniedrigt (wenn negativ) und dann die Endbedingung überprüft (siehe Details). Ist diese erfüllt, wird die Schleife verlassen, nämlich dann, wenn die Schleifenvariable des NEXT-Befehls größer (bei negativer Schrittweite kleiner) als der vorgegebene Endwert nach dem TO des FOR…TO…-Befehls ist. Ausnahme ist der Fall mit Schrittweite 0, wo die Schleifenvariable nur in Übereinstimmung mit dem Endwert, die Endbedingung erfüllt.
Der Ausdruck für den Endwert wird dabei aber nur zu Beginn einmalig ausgewertet und dann für jeden Schleifendurchlauf herangezogen.
Tritt die Endbedingung nicht ein, verzweigt die Programmausführung zurück zum Schleifenanfang, also zu dem unmittelbar nach dem FOR…TO…-Befehl folgenden Programmteil.

FOR-NEXT-Schleifen dürfen ineinander verschachtelt werden. Ein NEXT ohne Variablenangabe schließt dann immer das "innerste" und nächstliegende FOR, sonst jenes mit der dazu passenden Schleifenvariable. Etwaige innere Schleifen werden dabei zwangsweise abgebrochen und der Stapel korrekt bereinigt. Damit ist auch das Anspringen eines "äußeren" NEXT mittels GOTO möglich, um innere Schleifen frühzeitig und korrekt zu beenden. Umgekehrt führt das Anspringen von "inneren" Schleifen beim entsprechenden NEXT zu ?NEXT WITHOUT FOR ERROR.
Zu viele ineinander verschachtelt FOR-NEXT-Schleifen führen zur BASIC-Fehlermeldung ?OUT OF MEMORY ERROR. Das Limit von theoretisch 10 Verschachtelungen bewegt sich in der Praxis im Bereich rund um 8 bis 9, je nach dem, wie komplex die in der innersten Schleife durchzuführende Aktionen sein sollen: Berechnungen in mehreren Klammerebenen oder verschachtelte Unterprogrammaufrufe beanspruchen nämlich zusätzlich Platz auf dem Stapelspeicher und schränken die Verschachtelungstiefe ein.

Eine Schleife mit GOTO zu verlassen, ohne ein NEXT zu durchlaufen, sollte vermieden werden. Passiert dies mit jeweils verschiedenen Schleifenvariablen entsprechend oft (spätestens beim 11. Mal), erscheint die BASIC-Fehlermeldung ?OUT OF MEMORY ERROR aufgrund eines Stapelüberlaufs (bedingt durch die offen gebliebenen FOR-NEXT-Schleifen)!
Eine solche Situation ist aber eher die Seltenheit, bei der nämlich Schleifen mit verschiedenen Schleifenvariablen irgendwie aufeinander folgend eröffnet werden müssten. Immer wenn eine Schleifenvariable erneut bei einem FOR verwendet wird, verwirft dieses alle zeitlich nach dieser Variablen geöffneten (weiter verschachtelten, "inneren") Schleifen, wobei der Stapel im korrekten Zustand bleibt. Des weiteren werden bei einem RETURN alle seit dem dazugehörenden GOSUB geöffneten FOR-Schleifen beendet.

Speicherverbrauch[Bearbeiten | Quelltext bearbeiten]

Ein FOR-Aufruf belegt insgesamt 18 Bytes auf dem BASIC-Stapel. Diese setzen sich zusammen aus:

  • Adresse im BASIC-Text unmittelbar nach dem FOR-Befehl (2 Bytes)
  • Zeilennummer zur zuvor genannten BASIC-Text-Position gehörend (2 Bytes)
  • Schleifenendwert (Fließkommazahl, 5 Bytes)
  • Vorzeichen der Schrittweite: 0, 1 oder 255/$FF (-1) (1 Byte), entspr. der SGN-Funktion
  • Schrittweite (Fließkommazahl, 5 Bytes)
  • Adresse Schleifenvariable (2 Bytes)
  • FOR-Token 129/$81 (1 Byte) als Kennung

Die Werte werden wie am Stapel üblich ausgehend von hohen in Richtung niedriger Adressen abgelegt.

Geschwindigkeit[Bearbeiten | Quelltext bearbeiten]

Ein NEXT braucht in BASIC V2 des C64 nicht ganz 1000 Taktzyklen, also rund 1ms.

Beispiele[Bearbeiten | Quelltext bearbeiten]

Einfache Schleifen[Bearbeiten | Quelltext bearbeiten]

10 FOR X=1 TO 20: PRINT X: NEXT

Es werden die Zahlen 1-20 zeilenweise angezeigt.

10 FOR X=-10 TO 0 STEP 0.5: PRINT X: NEXT X

Es werden hier 20 Zahlen von -10 bis 0 angezeigt, da die Schrittweite 0.5 ist.

10 FOR X=100 TO -100 STEP -25: PRINT X: NEXT X

Es werden hier 9 Zahlen angezeigt und die Schleife wird herunter gezählt von 100 bis -100 mit der Schrittweite -25.

10 FOR X=10 TO 0 STEP -0.25: PRINT X: NEXT X

Diese Schleife zählt ebenfalls abwärts.

Verschachtelung[Bearbeiten | Quelltext bearbeiten]

10 FOR X=1 TO 10: PRINT: FOR Y=1 TO 10: PRINT X*Y;:NEXT Y,X

Hier erfolgt die Ausgabe des kleinen Einmaleins über zwei FOR-Schleifen, die mit einem NEXT-Befehl in der richtigen Reihenfolge geschlossen werden; erst die innere FOR-Y-Schleife, dann die äußere FOR-X-Schleife.

10 FOR I=1 TO 3
20 FOR J=1 TO 3
30 FOR K=1 TO 3
40 PRINT I,J,K 
50 IF RND(1)>0.5 GOTO 90 : REM K+J SCHLEIFE ABBRECHEN 
60 NEXT K
70 IF RND(1)>0.8 GOTO 20 : REM J-SCHLEIFE NEU STARTEN
80 NEXT J
90 NEXT I

Schleifenabbruch und -neustart: Drei ineinander verschachtelte Schleifen mit einem zufallsgesteuerten

  • Schleifenabbruch der inneren Schleifen durch direktes Anspringen des NEXT-Befehls der äußersten Schleife:
    Die übersprungenen Schleifen werden dabei abgebrochen (der Stapel entsprechend korrekt aufgeräumt). Die Stelle des Abbruchs kann bei Bedarf in der I-Schleife (zwischen Zeilen 10 und 20) anhand der Werte von J und K festgestellt werden.
  • Neustart der J-Schleife durch direktes Anspringen des FOR-Befehls.

Spezialfälle[Bearbeiten | Quelltext bearbeiten]

10 FOR I=1 TO 0:PRINT I:NEXT

...gibt eine "1" aus, da die Abbruchbedingung erst von NEXT geprüft wird.

10 I=10:FOR I=0 TO I:PRINT I:NEXT

...gibt eine "0" aus, da die Initialisierung von I in FOR vor dem Evaluieren des Endwerts ausgeführt wird.

10 EW=10:FOR I=0 TO EW:EW=100:PRINT I:NEXT

...gibt die Werte 0 bis 10 aus, da der Endwert von FOR nur einmalig evaluiert wird.

10 FOR I=0 TO 10:PRINT I:I=11:NEXT

...gibt eine "0" aus.

Ersatzimplementierung[Bearbeiten | Quelltext bearbeiten]

Initialisierung für beide Varianten:

10 AW=0
20 EW=10
30 SW=3

FOR-NEXT-Variante:

100 FOR I=AW TO EW STEP SW
110 PRINT I
120 NEXT

Nachgebildet mittels IF, THEN, GOTO:

100 :I=AW                : REM FOR ...
110 PRINT I
120 :I = I+SW            : REM NEXT ...
121 :IF SGN(I-EW) <> SGN(SW) GOTO 110

Die allgemeingültige Implementierung, wie sie der BASIC-Interpreter verwendet, auch für negative Schrittweiten!

Stolperfalle[Bearbeiten | Quelltext bearbeiten]

S=1:P=5:FORI=STOP:PRINTI:NEXT

liefert überraschenderweise einen Syntax-Error: Anstelle von S TO P wird der STOP-Befehl erkannt.
In diesem Fall kann man sich mit einem Leerzeichen nach dem S oder vor dem P behelfen, um den Fehler zu vermeiden.

Weitere Beispiele[Bearbeiten | Quelltext bearbeiten]

Siehe