IF

Der BASIC-Befehl IF (Wenn …) wird mit dem nachfolgenden BASIC-Befehl THEN (dann …) oder auch mit den BASIC-Befehl GOTO (springe zu …) genutzt, um abhängig von der Auswertung des Ausdrucks nach dem IF, etwa durch einen Vergleich, den Programmlauf zu steuern. Dabei gilt, wenn der Ausdruck „wahr“ ist (also einen Wert ungleich 0 ergibt) wird der anschließende BASIC-Befehl THEN oder GOTO ausgeführt. Wenn der Ausdruck logisch „unwahr“, also „falsch“ ist (den Wert 0 hat) wird der nachfolgende BASIC-Befehl THEN oder GOTO ignoriert und die dahinter folgenden BASIC-Befehle in dieser Zeile nicht mehr ausgeführt.
In der GOTO-Zeilennummer-Variante werden etwaige nach der Zeilennummer folgende Befehle (durch „:“ getrennt, wenn keine Ziffern auch ohne Doppelpunkt!) niemals ausgeführt und kommen somit einem Kommentar gleich.

Der dem IF-Befehl folgende Ausdruck verwendet üblicherweise Operatoren, um Vergleiche anzustellen, die eventuell zusammen mit logische Verknüpfungen noch komplexere Bedingungen bilden können. Das Ergebnis des Ausdrucks entscheidet jedenfalls über den weiteren Programmablauf und wird als Integer-Wert aufgefasst:

  • ungleich 0:
    entspricht einem „Wahr“ und der THEN- oder GOTO-Zweig wird aktiv.
  • gleich 0:
    entspricht einem „Falsch“ und der THEN- oder GOTO-Zweig wird übergangen.

Bei der Verwendung der Buchstabenfolge IF in einem Variablennamen, erscheint die BASIC-Fehlermeldung ?SYNTAX ERROR (z.B. PRINT WIFFY$).

Beispiele

Typische Verwendung

10 PRINT CHR$(147);
20 INPUT "Geben Sie bitte 2 beliebige Zahlen an";A$, B$
30 IF A$="" OR B$="" THEN 20
40 A=VAL(A$): B=VAL(B$)
50 IF A>0 THEN PRINT "A IST POSITIV UND ";
51 IF A<0 THEN PRINT "A IST NEGATIV UND ";
52 IF A=B THEN PRINT "A IST GLEICH B ";
53 IF A<>B THEN PRINT "A IST UNGLEICH B ";
54 IF NOT A AND NOT B THEN PRINT ", KEINE ZAHL IST -1";
55 IF A=64 AND B=64 THEN PRINT " !!! BINGO !!!": GOTO 58
56 IF A=B AND A=0 GOTO 58
57 IF (A AND B=0) OR (NOT B AND A=0) THEN END
58 FOR X=0 TO 3000: NEXT
59 GOTO 10

Das folgende Beispiel dient nur zum Verdeutlichen der internen Funktionsweise von IF bzw. den Vergleichsoperatoren:

10 IF -2 THEN PRINT "-2"
20 IF -1 THEN PRINT "-1"
30 IF  0 THEN PRINT " 0"
40 IF  1 THEN PRINT " 1"
50 IF  2 THEN PRINT " 2"
60 PRINT "1=1 IST ";(1=1)
70 PRINT "0=1 IST ";(0=1)
80 A=2 : REM HIER WIRD A=... ALS ZUWEISUNG INTERPRETIERT
90 PRINT "A=3 IST ";(A=3) : REM HIER WIRD A=... ALS VERGLEICH INTERPRETIERT
100 PRINT "A=2 IST ";(A=2)
READY.
RUN
-2
-1
 1
 2
1=1 IST -1
0=1 IST  0
A=3 IST  0
A=2 IST -1

Logische Operatoren

Einfache bitweise Verknüpfung:

10 IF ST AND 64 GOTO 99
...
99 PRINT "END OF FILE"

Wenn der Statuswert in Systemvariable ST das Bit 6 mit Wertigkeit 64 (= „End of File“) gesetzt ist und damit der Wert ungleich 0 ist (also das Bit gesetzt ist), wird verzweigt.

Kombinierte bitweise Verknüpfungen:

10 J = NOT PEEK(56320)
20 IF (J AND 2)>0 AND (J AND 8)>0 THEN PRINT "RECHTS UNTEN" 

Joystick Port 2 einlesen und auf Rechts-Unten-Bewegung abfragen.
Achtung: Falsch wäre folgende „Optimierung“:

20 IF (J AND 2) AND (J AND 8) THEN PRINT "RECHTS UNTEN" 

Hier sind die Klammerausdrücke bitweise Verknüpfungen, die die Werte 2 bzw. 8 ergeben können. Diese wiederum mit AND verknüpft ergibt bitweise(!) zusammengeführt immer 0, wodurch die IF-Bedingung nie zutreffend wird.

Implikation – Wenn-Dann-Konstrukt:

10 FOR P = 0 TO -1 STEP -1
20 FOR Q = 0 TO -1 STEP -1
30 PRINT P,"=>",Q,: IF P => Q THEN PRINT "WAHR": GOTO 50
40 PRINT "FALSCH"
60 NEXT Q, P
 0        =>         0        WAHR
 0        =>        -1        WAHR
-1        =>         0        FALSCH
-1        =>        -1        WAHR

Die Wertetabelle beschreibt den Zusammenhang: aus P folgt Q, aber nicht umgekehrt. Durch die Wertestruktur von 0 für „Falsch“ und -1 für „Wahr“ ergibt der Vergleichsoperator „=>“ (könnte auch „>=“ geschrieben sein) das logische Wenn-Dann-Verhalten.

Syntaktische Besonderheiten

Grenzfall: Kommentar ohne REM und ohne „:“ …

10 IF A > 0 GOTO 99 HIER IST EIN KOMMENTAR
20 PRINT "A IST <= 0!"
99 END

Kaskade:

10 IF X = 319 AND Y = 0 THEN PRINT "ECKE RECHTS OBEN"

In solchen Fällen müssen immer alle mit AND verknüpften Bedingungen überprüft werden. Wenn es eher selten ist, dass sie alle zutreffen, dann ist es aus Sicht der Ausführungsgeschwindigkeit besser die AND-Kette in eine IF-THEN-IF-Kaskade umzuwandeln:

10 IF X = 319 THEN IF Y = 0 THEN PRINT "ECKE RECHTS OBEN"

Damit wird bereits frühzeitig zur nächsten Zeile weiter gegangen, wenn schon klar ist, dass nicht alle Bedingungen eintreffen werden, ohne dabei alle folgenden Bedingungen auswerten zu müssen.

Vergleich: IF-GOTO-Äquivalent mit ON-GOTO:

10 IF A > 0 GOTO 99

entspricht im Wesentlichen

10 ON -(A > 0) GOTO 99 

allerdings mit dem Unterschied, dass bei der IF-Variante alles hinter dem GOTO ignoriert wird. In der ON-Variante wird die Ausführung unmittelbar nach einem „:“ fortgesetzt, wenn das Sprungziel nicht gewählt wurde.

Ungewöhnlichkeiten

Der IF-Befehl (auch bei den Nachfolgern zumindest bis BASIC 7.0) führt eine allgemeine Ausdrucksauswertung aus, dessen Ergebnis auch eine Zeichenkette sein kann. Allerdings wird dies von IF nicht explizit berücksichtigt, sodass hier unterschiedliche Effekte bei folgenden Fällen auftreten können:

  1. Der Ausdruck ist nur eine Stringvariable: In diesem Fall wird die Variable ignoriert (sie wird gesucht, aber der Wert wird nicht geholt) und das Ergebnis des zuletzt ausgewerteten Ausdrucks ist für Entscheidung des IF-Befehls maßgeblich.
  2. Der Ausdruck ist eine Zeichenkettenkonstante oder ein Ausdruck der die Operation „+“ enthält (die einzige erlaubte Operation): In diesem Fall ist Länge des Ergebnisses ausschlaggebend, wobei eine Länge größer 0 einem „wahr“ entspricht. Als Nebeneffekt belegt das Ergebnis ein Element des Stringdescriptorstacks (mit Platz für 3 Elemente), welcher im weiteren Verlauf nicht mehr bereinigen lässt und spätestens nach dem 3. solchen Vorkommnis bei der nächsten Ausdrucksauswertung zum Abbruch mit Fehler ?FORMULA TOO COMPLEX ERROR führt.

Beispiele zu Fall 1:

10 A=1
20 IF R$ THEN PRINT "A="A"IST WAHR"
30 A=0
40 IF R$ THEN PRINT "A="A"IST WAHR"
50 B$="1"
60 IF R$ THEN PRINT "B$="B$" IST WAHR"
70 B$=""
80 IF R$ THEN PRINT "B$="B$" IST WAHR"

ergibt (der Inhalt der Variable R$ spielt keine Rolle)

A= 1 IST WAHR
B$=1 IST WAHR

Anwendungsfall:

100 F=1-F:IF TRUE$ THEN "TU WAS, WEIL F=1"

Hier erspart man sich durch Abfrage der Dummy-Variablen TRUE$ (bzw. TR$) eine explizite Prüfung des Wertes in Variable F. D.h. die Berechnung von F ergibt gleich automatisch die Prüfung.
Beispiele zu Fall 2:

10 IF "" THEN PRINT "LEER IST WAHR"
20 IF "X" THEN PRINT "NICHT LEER IST WAHR"
30 IF A$+"X" GOTO 30

gibt aus

NICHT LEER IST WAHR
?FORMULA TOO COMPLEX  ERROR IN 30

Das GOTO wird dabei genau einmal durchlaufen, d.h. bei der 2. Abarbeitung der Zeile 30 wäre dann ein 4. Eintrag auf dem Stringdescriptorstack nötig, was aber bei der dabei erfolgten Überprüfung in einen Abbruch mündet.