Schleife

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Eine Schleife dient dazu, einen einzelnen Programmbefehl oder einen ganzen Programmabschnitt vom Interpreter mehrmals durchführen zu lassen. Programme werden für den Programmierer übersichtlicher und sind damit vor allem in der Fehlerkorrekturphase leichter zu handhaben. Es gibt vier grundsätzliche Schleifenkonstrukte: die Endlosschleife, die kopfgesteuerte Schleife, die fußgesteuerte Schleife und die Zählschleife (weitere Erläuterungen beim Simons'-Basic-Befehl LOOP und weiter unten bei LOOP EXIT END LOOP mit FOR-NEXT).

BASIC Version 2 des C64 kennt nur als strukturierte Schleife das Konstrukt FOR...NEXT, andere Programmiersprachen wie Pascal oder C, aber auch Basic-Erweiterungen (z.B. das oben erwähnte Simons' Basic) oder höhere CBM-BASIC-Versionen (z.B. ab BASIC 3.5) kennen weitere Schleifenarten wie WHILE-DO, DO-WHILE (kopfgesteuerte Schleifen), REPEAT-UNTIL (fußgesteuerte Schleife) oder LOOP-END LOOP.

Bei ineinander verschachtelten Schleifen ist es ratsam, dass der Übersicht halber die Programmstruktur mit den äußeren und inneren Schleifen gewahrt bleibt. Es ist durchaus möglich, mit Hilfe eines GOTOs das Ende einer Schleife bzw. sogar aus einer Schleife heraus zu springen, oder ein zu einer bestimmten Schleife gehörendes NEXT kann auch an mehreren Stellen vorkommen. Der BASIC-Stapel (engl. Stack) wird in den meisten Fällen entsprechend aufgeräumt. Allerdings kann dies zu einem schwer verständlichen bzw. fehlerträchtigen Programmcode führen, da folgende Situationen auftreten können:

  • Ein NEXT ohne Angabe einer Schleifenvariablen bezieht sich immer auf die gerade innerste Schleife, was bei GOTO-Sprüngen nicht mehr klar nachvollziehbar sein könnte.
  • Eine Schleife mit einer Variable wird erneut geöffnet (wobei etwaige zuvor schon geöffnete Schleife mit allen seinen inneren Schleifen) automatisch "geschlossen" werden. Ein NEXT <Schleifenvariable> bezogen auf eine dieser inneren Schleifen führt zu einem Fehler ?NEXT WITHOUT FOR ERROR.
  • Ein Unterprogramm (GOSUB) mit einer Schleife wurde mittels RETURN verlassen, welches alle dort geöffneten Schleifen "abbaut" bzw. verwirft. Gibt es dann in weiterer Folge einen Bezug mittels NEXT auf eine der im Unterprogramm befindlichen Schleife, führt auch das zu einem ?NEXT WITHOUT FOR ERROR.
  • In einem Unterprogramm wird versucht eine zuvor eröffnete Schleife mit einem NEXT <Schleifenvariable> fortzusetzen. Auch dies wird mit der Meldung ?NEXT WITHOUT FOR ERROR geahndet.

Wenn mehrere Schleifen miteinander verschachtelt sind, dann ist auf das Limit (gegeben durch den BASIC-Stapel) der unterschiedlichen hier zum Einsatz kommenden Schleifenvariablen zu achten, was z.B. in gegenseitigen Unterprogrammaufrufen leicht aus den Augen zu verlieren drohen könnte. In solchen Fällen kann es zu einem unerwarteten ?OUT OF MEMORY ERROR kommen.


Dieses folgende Beispiel wird unten durch entsprechende Schleifen vereinfacht:

10 PRINT CHR$(147): A=0: B=0: DIM X$(4)
20 READ X$(0): PRINT X$(0)
21 READ X$(1): PRINT X$(1)
22 READ X$(2): PRINT X$(2)
23 READ X$(3): PRINT X$(3)
24 READ X$(4): PRINT X$(4)
30 DATA "Guten Tag"
31 DATA "Ich bin der Commodore 64"
32 DATA "Ich arbeite immer sehr zuverlässig"
33 DATA "Schon seit 1982"
34 DATA "Ich hoffe Du hast mit mir viel Spass"


FOR-NEXT-Schleife[Bearbeiten | Quelltext bearbeiten]

Bis zur BASIC-Version 2 gibt es nur die FOR-NEXT-Schleife, die ausgeschrieben als FOR…TOSTEP…NEXT-Schleife formuliert werden muss. Laut Programmier-Syntax erfolgt die Benutzung innerhalb von BASIC-Programmen wie folgt:

10 FOR <Schleifenvariable>=<Startwert> TO <Endwert> [STEP <Schrittweite>]
20  ...weitere Befehle...
30 NEXT [<Schleifenvariable>]


Das oben genannte Beispiel lässt sich mit FOR-NEXT wie folgt umsetzen:

10 PRINT CHR$(147): A=0: B=0: DIM X$(4)
20 FOR X=0 TO 4 STEP 1
21 READ X$(X): PRINT X$(X)
22 NEXT X
30 DATA "Guten Tag"
31 DATA "Ich bin der Commodore 64"
32 DATA "Ich arbeite immer sehr zuverlässig"
33 DATA "Schon seit 1982"
34 DATA "Ich hoffe Du hast mit mir viel Spass"

Anmerkungen:

  • Da die Schrittweite standardmäßig +1 ist, könnte das STEP 1 weggelassen werden.
  • Weiterhin kann ebenfalls die Variablenangabe X hinter dem NEXT weggelassen werden, da standardmäßig immer die zuletzt geöffnete Schleife geschlossen wird.

Schleifenersatz mit IF-THEN-GOTO[Bearbeiten | Quelltext bearbeiten]

Falls keine der oben genannten Schleifen in einer Programmiersprache zur Verfügung steht, können diese auch mit IF-THEN und GOTO nachgebildet werden.

Das oben genannte Beispiel mit IF-THEN-GOTO:

10 PRINT CHR$(147): A=0: B=0: DIM X$(4)
20 X=0: REM Anfangswert der Schleife
21 READ X$(X): PRINT X$(X)
22 X=X+1: REM Schrittweite
23 IF X<=4 THEN GOTO 21: REM Prüfung auf Schleifenende
30 DATA "Guten Tag"
31 DATA "Ich bin der Commodore 64"
32 DATA "Ich arbeite immer sehr zuverlässig"
33 DATA "Schon seit 1982"
34 DATA "Ich hoffe Du hast mit mir viel Spass"

LOOP - EXIT - END LOOP mittels FOR-NEXT[Bearbeiten | Quelltext bearbeiten]

Die FOR-NEXT-Schleife lässt sich aufgrund dieser Eigenschaften auch generell als Ersatz für schnelle Schleifen (siehe Laufzeitverhalten) analog zu LOOP - EXIT - END LOOP verwenden.

100 FOR I=0 TO 1 STEP 0            : REM LOOP
110 REM MACH ETWAS
...
150 IF (ABBRUCH) THEN I=1:GOTO 190 : REM EXIT
160 REM MACH NOCH WAS
...
170 IF (NOCHMAL) THEN NEXT I       : REM AGAIN
180 REM TU ETWAS ANDERES
...
190 NEXT I                         : REM END LOOP

Interessant dabei ist auch die Eigenschaft, ein sogenanntes AGAIN-Element nebenbei zu gewinnen, das in manchen Programmier- oder Script-Sprachen auch als continue, next oder redo bekannt ist. Es bewirkt bei diesem Schleifentyp einfach einen Rücksprung an den Schleifenanfang. Damit beendet man diesen einen Schleifendurchlauf frühzeitig, die Schleife selbst bleibt aber weiterhin aktiv.

Laufzeitverhalten[Bearbeiten | Quelltext bearbeiten]

Die FOR-NEXT-Konstruktion ist bei BASIC V2 insofern sehr effizient, da der NEXT-Rücksprung zum Anfang der Schleife kaum eine Verzögerung mit sich bringt. Das liegt daran, dass das Rücksprungziel direkt am BASIC-Stapel vermerkt ist (siehe Details bei FOR).
Eine gleichwertige Logik mit IF-THEN-GOTO nachgebildet, leidet unter dem Nachteil, dass beim Rücksprung mittels GOTO die Zeile des Schleifenbeginns erst gesucht werden muss. Das kann recht aufwendig werden, wenn vom Programmanfang (wo die Suche beginnt) bis zum Schleifenbeginn viele Zeilen vorhanden sind. Das heißt, die Zeit für einen Schleifendurchlauf ist variabel und hängt wesentlich von der Lage der Schleife und der Zeilenzahl vor der Schleife im Programm ab.