GOTO

Aus C64-Wiki
Zur Navigation springenZur Suche springen
GOTO
Syntax: GOTO [<Zeilennummer>]
Parameter
<Zeilennummer>: Zeilennummer, die angesprungen wird
Einordnung
Typ: Anweisung
Kontext: Programmstruktur
Aufgabe: Sprung zu angegebener Zeilennummer
Abkürzung: gO
Token: $89 (137) / $cb $a4 (203 164)
Verwandte Befehle
GOSUB, ON, RETURN, TO

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


Der BASIC-Befehl GOTO lässt den BASIC-Interpreter zur angegebenen Zeilennummer springen und die Abarbeitung des BASIC-Programms wird an dieser Stelle fortgesetzt. Die Zeilennummer muss eine numerische Konstante sein, deren Wert im Bereich für Zeilennummer von 0 bis 63999 liegen sollte (darüber liegende Werte führen zu einem ?SYNTAX ERROR). Der Zahlenwert wird lediglich aus jenen Ziffern gebildet (es können auch Leerzeichen eingestreut sein), bis auf eine Nicht-Ziffer gestoßen wird. Dieses und folgende Zeichen bis zum Zeilenende werden ignoriert (gelten sozusagen als Kommentar).
Ein fehlender Parameter wird als Zeilennummer 0 verstanden - führt also nicht zwangsläufig zu einem Fehler (nur wenn die Zeile 0 nicht existiert, was aber zur Fehlererkennung empfehlenswert ist).

Ein weiteres Einsatzgebiet ist die bedingte Programmflusssteuerung, wo sich die GOTO-Funktion in den Konstruktionen IF...THEN, IF...GOTO, ON...GOTO wieder findet (siehe Beispiele, Zeile 31).

Mit dem BASIC-Befehl GOTO können auch Endlosschleifen programmiert werden. Der Programmcode 55 GOTO 55 lässt sich nur noch durch Drücken der Taste RUN/STOP  unterbrechen.

Der BASIC-Befehl GOTO kann im Direktmodus dazu genutzt werden, um so ähnlich wie beim BASIC-Befehl RUN <Zeilennummer> oder nach einer Unterbrechung mittels CONT Programme auch ab einer bestimmten Zeilennummer zu starten oder weiterlaufen zu lassen.
War das Programm zuvor bereits aktiv oder wurde es mit RUN/STOP  oder einem STOP- oder END-Befehl innerhalb des Programms angehalten, bleiben alle aktuellen Variablen-Werte erhalten. Im Gegensatz dazu hätte ein erneuter Start mit RUN die Auswirkung, dass alle Variablen gelöscht und die Zustände von Schleifen und Unterprogrammen zurückgesetzt werden (vergleiche auch CLR).

Die Schreibweise GO TO ist ebenso möglich, benötigt aber mehr Programmspeicherplatz (2 Byte mehr: für Leerzeichen und ein zusätzliches Token), was auch zum Nachteil in der Ausführungsgeschwindigkeit gereicht. Der Vorteil der besseren Lesbarkeit fällt eher gering aus. Zudem ist diese Schreibweise bei ON-GOTO-Anweisungen nicht möglich.

Existiert die Zeilennummer nicht, die angesprungen werden soll, wird die BASIC-Fehlermeldung ?UNDEF'D STATEMENT ERROR ausgegeben. Liegt die Zeilennummer außerhalb des zulässigen Bereichs, wird mit ?SYNTAX ERROR abgebrochen.

Geschwindigkeit[Bearbeiten | Quelltext bearbeiten]

Der Interpreter geht die Zeilen der Reihe nach durch, bis er die richtige Zeile gefunden hat. Liegt die Zeilennummer des Ziels vor dem GOTO-Befehl, beginnt der Interpreter die Suche nach der Zielzeile vom Start des Programms an, sonst von der Zeile, in der er sich gerade befindet.

Das heißt, dass zum Beispiel GOTOs, die in langen Programmen weit hinten stehen und nur einen kleinen Sprung nach vorne machen (auch in die gleiche Zeile), relativ langsam sind. Z.B. braucht ein 1000 I=I+1:IFI<100THEN1000 als alleinige Zeile rund 850 Millisekunden, als 1000ste Zeile in einem Programm jedoch rund sieben Sekunden. In diesen Fällen ist eine FOR/NEXT-Schleife vorzuziehen, da der implizite Rücksprung bei NEXT ohne Suche der Programmzeile auskommt.

Mit BASIC-Compilern kompilierte Programme haben dieses Problem nicht.

Fehler[Bearbeiten | Quelltext bearbeiten]

Zeilennummeranomalie[Bearbeiten | Quelltext bearbeiten]

Effekt
Bei einer mindestens 6-stelligen Zeilennummer beginnend mit einer Zahl im Bereich von 35072 bis 35327 (z. B. GOTO 350720) kommt es bei der Ausführung nicht zum erwarteten Fehler ?SYNTAX ERROR, sondern es passiert ein Absturzeffekt:
  • C64: Wie bei Drücken der Tastenkombination RUN/STOP +RESTORE 
  • VC20: Stürzt ab nach einer Folgeaktion, eventuell mit vorhergehender Anzeige einer Fehlermeldung.
  • C116/C16/Plus/4 BASIC 3.5: Die Darstellung im Textmodus wird korrumpiert, der Cursor erscheint wieder.
  • PET bis BASIC 4.0: Stürzt ab.
Nicht betroffen:
Ursache
Wenn bei der Abfrage des maximal erlaubten Zeilennummerwertes sich ein Wert ergibt, der in der hexadezimalen Darstellung $89xx lautet und damit größer als $1900 (=6400) ist, was die Grenze für das überschrittene Zeilennummermaximum (64000) bei 4 Ziffern ist (so noch eine Ziffer folgt), dann ist der höherwertige Teil des Wertes $89, was dem GOTO-Token entspricht. Genau dann entsteht das Schlupfloch an Stelle $A953, durch den der sonst funktionierenden Trick zur Code-Einsparung (besser gesagt in Umgehung des fehlenden BRA-Maschinensprachebefehls) nicht funktioniert. Dabei wird versucht den Einsprungspunkt für einen Syntax-Error in der nahen ON-Token-Verarbeitung mit einem bedingten Branch-Befehl zu erreichen. Ungünstigerweise nimmt man dabei in Kauf, dass die Stelle auch von der Abfrage auf das GOTO-Token $89 angesprungen wird (und insgeheim davon ausgeht, dass der Akkumulator nicht gerade zufälligerweise diesen Wert hat). Mit obigem Dezimalwert passiert es aber dennoch und statt mit Syntax-Error zu beenden, verirrt sich der Interpreter in den ON-GOTO/GOSUB-Teil (siehe $A97D), wo von anderen Bedingungen am Stack ausgegangen wird und dieser dann durcheinander gerät und damit einen korrekten Rücksprung verhindert.


Beispiele[Bearbeiten | Quelltext bearbeiten]

Beispiel 1[Bearbeiten | Quelltext bearbeiten]

Eingabeabfragen und entsprechende Verzweigungen:

10 C=0: PRINT CHR$(147);: INPUT "Geben Sie bitte eine Zahl ein "; A
20 PRINT "Geben Sie bitte eine weitere Zahl ein "; 
30 INPUT B: IF C=1 AND B=0 GOTO 30
31 IF C=1 AND B<>0 GOTO 74
40 C=1: INPUT "Geben Sie bitte ein Rechenzeichen ein (+-/*) "; A$
50 IF A$<>"+" OR A$<>"-" OR A$<>"*" OR A$<>"/" GOTO 30
60 IF B=0 AND A$="/" THEN PRINT "Division durch 0 unmoeglich. Korrektureingabe:";: GO TO 30
70 IF A$="+" THEN C=A+B: B$="ADDITION"
71 IF A$="-" THEN C=A-B: B$="SUBTRAKTION"
72 IF A$="*" THEN C=A*B: B$="MULTIPLIKATION"
73 IF A$="/" THEN C=A/B: B$="DIVISION"
74 PRINT "Sie waehlten: " B$
75 PRINT "Das Ergebnis lautet: " C
80 INPUT "Noch eine Berechnung durchfuehren (J=JA, Abbruch andere Zeichen)"; A$
90 IF A$="J" THEN GOTO 10

Beispiel 2[Bearbeiten | Quelltext bearbeiten]

Provokation eine fehlerhaften Fehlerbehandlung:

GOTO350720

führt zu einem unerwünschten Effekt (Absturz). Siehe Fehler-Abschnitt.


Beispiel 3[Bearbeiten | Quelltext bearbeiten]

Da die Angaben hinter der GOTO-Zeilennummer nicht interpretiert werden, kann man hier einen Kommentar schreiben, ohne REM benutzen zu müssen:

GOTO 200 FEHLERBEHANDLUNG

Achtung: das erste Zeichen des Kommentars - auch wenn ein Leerzeichen die Zeilennummer und den Kommentar trennt - darf keine Ziffer sein!