2.5 Programmablaufsteuerung2.5.1 Verzweigungen: IF-THEN-ELSE, ON SWITCH 2.5.2 Schleifen: FOR-NEXT, WHILE-WEND, REPEAT-UNTIL, BREAK, CONTINUE 2.5.3 Pause und Delay: PAUSE, DELAY 2.5.4 Unbedingte Sprünge: GOTO, LABEL 2.5.5 Vorzeitiger Programmabbruch: EXIT, END ^2.5.1 VerzweigungenIn vielen Fällen muss R-BASIC Entscheidungen treffen und je nach Situation unterschiedliche Dinge tun. Für einfache Fallunterscheidungen stehen die Befehle IF ... THEN ... ELSE (falls ... dann ... ansonsten) zur Verfügung.Für die Unterscheidung von mehr als zwei Fällen gibt es die Anweisung ON .. SWITCH. Entscheidungen mit IF - THEN - ELSEDie Anweisung IF prüft den auf IF folgenden numerischen Ausdruck. Ergibt dieser einen Wert ungleich Null wird er als WAHR interpretiert und der THEN-Zweig wird abgearbeitet. Ergibt er den Wert NULL, so wird der ELSE-Zweig abgearbeitet.Für IF stehen zwei Formate zur Verfügung: Das Standard-Format und das Kurz-Format. Beim Standard-Format muss THEN die letzte Anweisung in der Code-Zeile sein, beim Kurzformat folgen auf THEN weitere Anweisungen in der gleichen Zeile. Details dazu siehe unten. Standard-Syntax:
Beispiel: |
IF A > 0 THEN PRINT "Positiv" ELSE PRINT "Nicht positiv" END IF |
| Beispiel Standard-Format ohne ELSE-Zweig |
IF X < 0 AND g$ = "m" THEN PRINT "Ich habe gar kein Auto." END IF |
KurzformIn vielen Fällen müssen, falls die Bedingung wahr ist, nur einer oder wenige Befehle abgearbeitet werden. Für diesen Zweck unterstützt R-BASIC eine Kurzform der IF-Anweisung. Dabei müssen alle Anweisungen des THEN- und des ELSE- Zweigs in der gleichen Code-Zeile wie die IF-Anweisung stehen.Syntax: IF < Bedingung> THEN <THEN-Zweig> : ELSE <ELSE-Zweig> bzw.: IF < Bedingung> THEN <THEN-Zweig> Beispiel: |
IF Name$ = "Paul" THEN Print "Paul gefunden" |
Hinweise:
Kompatibilität:Aus Gründen der Kompatibilität werden in der Kurzform von IF auch die folgenden Formate unterstützt. Sie sollten diese Formate in eigenen Programmen aber nicht einsetzen.
Beispiele zur IF-AnweisungFür das normale IF-Format muss THEN am Ende einer Zeile stehen. Kommentare hinter THEN sind aber erlaubt. ELSE muss nicht allein in einer Zeile stehen. Hinter ELSE kann man den Doppelpunkt weglassen: |
IF A > B THEN ' Ich bin ein Kommentar A = A - 2 : B = B + 1 ELSE PRINT "Fertig" : END IF |
|
Neben logischen Ausdrücken mit Zahlen können auch Zeichenketten verglichen werden (Temp$, Name$ und AlterName$ seien String-Variablen) |
IF Name$ > AlterName$ THEN Temp$ = Name$ ' Vertauschen der Namen Name$ = AlterName$ AlterName$ = Temp$ END IF |
|
Logische Operatoren in IF-Anweisungen sind sehr hilfreich. Bitte beachten Sie die Hierarchie der Operatoren oder setzen Sie Klammern! |
Label nochmal: ' Rücksprungmarke INPUT "Bitte A eingeben"; A IF A < 0 OR A > B THEN Print "A ist ungültig" GOTO nochmal END IF |
|
Numerische Ausdrücke sind WAHR, wenn sie nicht Null sind. |
IF A THEN Print "A ist nicht Null" |
IF 17 * A - B THEN Print "17 * A ergibt nicht B" |
|
IF-Anweisungen können ineinander verschachtelt werden. Vorsicht! Das wird sehr schnell unübersichtlich und daher fehleranfällig. Die Farben deuten im Beispiel die Zugehörigkeit an. |
IF A > 0 THEN
PRINT "Positiv"
ELSE
IF A = 0 THEN
PRINT "Null"
ELSE
PRINT "Negativ"
END IF
END IF
|
MehrfachverzweigungenZur Unterscheidung von mehr als zwei Fällen steht die Anweisung ON ... SWITCH (je nach ... schalte um) zur Verfügung.Syntax:
Beispiel (A sei eine numerische Variable): |
ON A SWITCH CASE 0: Print "A ist Null" END CASE CASE 1: Print "A ist 1" END CASE DEFAULT: Print "A nicht Null oder 1" END SWITCH |
|
Bedeutung der Werte:
Beispiel: |
CASE 1: Print "A ist 1" CASE 2: ' hier kein END CASE davor Print "A ist 1 oder 2" END CASE |
Hinweise:
|
CASE 1: IF B > 0 THEN END CASE CASE 2: Print "A ist 1 oder 2" END CASE |
|
Einfache Beispiele: |
INPUT "Geben Sie bitte A ein"; A
ON A SWITCH
CASE 1:
Print "A ist 1"
END CASE
CASE 2:
Print "A ist 2"
END CASE
DEFAULT:
Print "A ist weder 1 noch 2" ' END CASE kann hier entfallen
END SWITCH
|
|
Hinter CASE sind einfache Berechnungen und die Funktionen INT(), ASC() und SizeOf() zugelassen (siehe vorne). |
DIM A$ ' String-Variable
INPUT "Geben Sie einen Text ein"; A$
ON ASC(A$) SWITCH ' ersten Buchstaben testen
CASE ASC("A"):
Print "Der erste Buchstabe ist ein A"
END CASE
CASE ASC("z"):
Print "Der Text beginnt mit einem kleinen z."
' END CASE kann hier entfallen
END SWITCH
|
|
Beispiel für kurze CASE-Fälle |
INPUT "Geben Sie bitte A ein"; A ON A SWITCH CASE 1: Print "A ist 1" : END CASE CASE 2: Print "A ist 2" : END CASE DEFAULT: Print "A ist weder 1 noch 2" END SWITCH |
|
Mehrere Fälle mit dem gleichen Code: |
INPUT "Geben Sie bitte A ein"; A
ON A SWITCH
CASE -1:
CASE 0:
CASE 1:
Print "A ist -1, Null oder 1"
END CASE
CASE 2: CASE 3: CASE 4:
Print "A ist 2, 3 oder 4"
END CASE
CASE -5:
CASE 5:
Print "A ist 5 oder -5"
END CASE
DEFAULT:
Print "Nichts passendes gefunden."
END SWITCH
|
|
Verschachtelung von ON..SWITCH-Anweisungen. Die Farben deuten im Beispiel die Zugehörigkeit an. A und B sind REAL-Variablen. |
InputBox "A und B eingeben", A,B
ON A SWITCH
CASE 0:
CASE 1:
PRINT "Fall 1"
IF B = 1 THEN PRINT "B ist 1"
END CASE
CASE 2:
PRINT "Fall 2"
ON B SWITCH
CASE 1:
PRINT "B ist 1"
END CASE
DEFAULT
PRINT "B ist nicht 1"
END SWITCH
END CASE
DEFAULT
PRINT "sonstiges"
END SWITCH
PRINT "fertig."
|
|
Aus Kompatibilitätsgründen werden auch die folgenden Varianten unterstützt: ON <Ausdruck> GOTO <Liste von Zielen> ON <Ausdruck> GOSUB <Liste von Zielen> <List von Zielen> Sprungziele, die angesprungen werden, wenn der <Ausdruck> die Werte 1, 2, 3, 4 usw. ergibt. Beispiele (A sei eine numerische Variable) |
ON A GOTO 10, 20, 30 ' Zeilennummern |
ON A GOSUB L1, L2, L3 ' Labels |
DIM A Input A ON A GOSUB L1, L2, L3 Print "Fertig" End LABEL L1 PRINT "A ist Eins" : Return LABEL L2 Print "A ist Zwei" : Return LABEL L3 Print "A ist Drei" : Return |
Wie Sie sehen, kann man mit der GOTO bzw. GOSUB-Anweisung sehr unübersichtlichen Code erzeugen.
^2.5.2 SchleifenSehr häufig ist es erforderlich einen bestimmen Codeabschnitt mehrfach zu durchlaufen. Ein typischer Fall ist die Ausgabe einer Tabelle oder einer Liste von Namen. Eine solche Programmstruktur bezeichnet man als Schleife. In R-BASIC stehen Ihnen drei Schleifentypen zur Verfügung:
Zähl-SchleifenDie Zählschleife mit FOR wird verwendet, wenn man die Anzahl der Schleifendurchläufe im Voraus kennt. Die FOR-Schleife wird immer mindestens einmal durchlaufen.
Das folgende Beispiel gibt die Zahlen von 1 bis 4 aus: |
DIM N
FOR N = 1 TO 4
Print N
NEXT N
|
Bedeutung der einzelnen Elemente:
|
FOR N = 0 TO 10 ' 11 Durchläufe PRINT N, N * N NEXT N |
FOR N = 1 TO 10 STEP 0.5 ' 20 Durchläufe PRINT N, N * N NEXT N |
| Schleifen können verschachtelt werden. Die Farben deuten die Zugehörigkeit an. |
FOR X = 10 TO 30
FOR Y = 24 TO 58
PSet X, Y
NEXT Y
NEXT X
|
Hinweise:
|
FOR N = 0 TO 4 STEP 0.4 PRINT N, N * N NEXT N PRINT N - 4 ' ist NICHT Null! |
|
FOR N = 0 TO 4.2 STEP 0.4 |
|
Aus Gründen der Abwärtskompatibilität sind die folgenden Syntaxvarianten für NEXT erlaubt:
|
FOR N = 0 TO 4 PRINT N, N * N NEXT |
|
FOR X = 10 TO 30
FOR Y = 24 TO 58
PSet X, Y
NEXT Y, X
|
Die WHILE - WEND -SchleifeDie While-Wend-Schleife wird verwendet, wenn die Anzahl der Schleifendurchläufe noch nicht im Voraus fest steht. While-Wend ist abweisend, d.h. ist die Bedingung hinter While von Anfang an FALSCH, wir die Schleife nie durchlaufen.
Beispiel |
DIM A Print "Geben Sie eine Zahl größer als Null ein." A = -1 WHILE A <= 0 Input "Positive Zahl"; A WEND Print "Prima." |
Bedeutung der einzelnen Elemente:
|
A = 12 B = 34 WHILE A > 0 AND B > 0 A = A - 1 B = B - 10 PRINT A, B WEND |
' einen Text verlängern ' Aus "Hallo Welt" wird "Hallo Welt.........." InputBox "Bitte einen Text eingeben"; C$ WHILE Len(C$) < 20 C$ = C$ + "." WEND PRINT C$ + "!" |
' warten auf die Enter-Taste WHILE InKey$ <> Chr$(13) : WEND ' Doppelpunkt beachten |
Die REPEAT - UNTIL - SchleifeDie Repeat-Until-Schleife wird verwendet, wenn die Anzahl der Schleifendurchläufe noch nicht im Voraus fest steht. Repeat-Until ist nicht abweisend, d.h. die Schleife wird in jedem Fall mindestens einmal durchlaufen.
Bedeutung der einzelnen Elemente:
|
A = -7 REPEAT InputBox "Geben Sie eine positive Zahl ein", A UNTIL A > 0 PRINT A ' A ist jetzt immer positiv |
A = 12 B = 34 REPEAT A = A - 1 B = B - 10 PRINT A, B UNTIL A <= 0 AND B <= 0 |
' einen Text verlängern ' Aus "Hallo Welt" wird "Hallo Welt.........." InputBox "Bitte einen Text eingeben", C$ REPEAT C$ = C$ + "." UNTIL Len(C$) >= 20 PRINT ">>" + C$ + "<<" |
' warten auf die Enter-Taste REPEAT UNTIL InKey$ = Chr$(13) ' Doppelpunkt ist nicht nötig |
! Schleifenabbruch mit Enter REPEAT x = 1000* RND() ' Zufallszahl von 0 bis 999 Print x UNTIL InKey$ = Chr$(13) Print "Abbruch erfolgte bei"; x |
BREAK und CONTINUEBreak und Continue beenden eine Schleifendurchlauf oder eine Schleife vorzeitig.Syntax: BREAK Syntax: CONTINUE BREAK beendet eine Schleife (While-Wend, For-To-Next oder Repeat-Until) vorzeitig. Die Abarbeitung wird mit dem auf die Schleife folgenden Befehl (also hinter Wend, Next oder Until) fortgesetzt. CONTINUE beendet einen Schleifendurchlauf einer While-Wend, For-To-Next oder Repeat-Until Schleife vorzeitig. Die Schleifenbedingung wird erneut geprüft, da CONTINUE zum Schleifen-End-Befehl (Wend, Next oder Until) springt. Beispiele: |
! Auslassen von bestimmten Zahlen in einer Schleife FOR N = 1 TO 5 IF N = 3 THEN CONTINUE Print N NEXT |
Ausgabe: 1
2
4
5
|
! Vorzeitiger Abbruch einer Schleife FOR N = 1 TO 5 IF N = 3 THEN BREAK Print N NEXT |
Ausgabe: 1
2
|
! Schleifenabbruch per Zufall REPEAT x = 1000 * RND() ' Zufallszahl von 0 bis 999 IF x > 990 THEN BREAK Print x UNTIL FALSE ' Endlos-Schleife Print "Abbruch erfolgte bei"; x |
^2.5.3 Pause und DelayDie Befehle Pause und Delay dienen dazu, den Programmablauf für eine bestimmte Zeit anzuhalten. Pause und Delay werden vor allem in klassischen BASIC-Programmen verwendet. In objektorientierten Programmen sind Pause und Delay zu Fehlersuche hilfreich. Ansonsten sollten Sie diese Befehle in objektorientierten Programmen nicht verwenden. Stattdessen sollten Sie einen Timer verwenden, wenn Sie einen zeitgesteuerten Programmablauf wünschen. Timer sind ausführlich im Handbuch "Spezielle Themen", Kapitel 16, beschrieben.PAUSEDer Pause-Befehl bewirkt eine kurze Programmunterbrechung.Syntax: PAUSE [n]
Beispiel: |
PAUSE 2.5 ' Eine viertel Sekunde warten |
DELAYProgramm-Verzögerung. Der Befehl DELAY (verzögere) wartet, bis seit dem letzten DELAY-Befehl eine bestimmte Zeit vergangen ist. Im Gegensatz zum PAUSE-Befehl werden die zwischenzeitlich abgearbeiteten Befehle berücksichtigt. Damit ist eine gezielte Steuerung der Programmablaufgeschwindigkeit möglich. Nach Möglichkeit sollen Sie, z.B. für Spiele, statt Delay einen Timer verwenden. Syntax: DELAY [ InitWert ]
Das Programm wird erst fortgesetzt, wenn seit dem letzten DELAY-Befehl (mit oder ohne InitWert) mindestens "InitWert" Timer-Tics vergangen sind. Ist bereits eine längere Zeit vergangen wird das Programm sofort fortgesetzt. Beispiel: Langsame Ausgabe eines Textes, Buchstabe für Buchstabe |
DELAY 30 ' Eine halbe Sekunde Input A$ FOR N = 1 To Len(a$): PRINT Mid$(a$, N, 1); ' Einen Buchstaben ausgeben DELAY NEXT |
^2.5.4 Unbedingte SprüngeSchleifen und Verzweigungen springen zu einem anderen Programmteil wenn bestimmte Bedingungen erfüllt sind. Ein unbedingter Sprung hingegen wird in jedem Fall ausgeführt. Sie sollten die häufige Verwendung des GOTO-Befehls vermeiden, da er schnell zu sehr unübersichtlichen Programmen (dem sogenannten Spaghetti-Code, siehe Bild) führen kann.
GOTODie Anweisung GOTO (Gehe zu) setzt den Programmablauf an der angegebenen Stelle fort.Syntax: GOTO <sprungZiel>
LABELDie Anweisung LABEL (Marke) vereinbart ein Ansprungziel für GOTO, GOSUB oder RESTORE. Siehe auch Kapitel 2.11.4 (Data-Zeilen).Beispiel: |
IF A > 0 THEN GOTO MeineMarke ' Springt nach unten <Anweisungen 1> ' Werden ausgeführt wenn A nicht > 0 ist LABEL MeineMarke: <Anweisungen 2> ' Werden in jedem Fall ausgeführt |
| In den meisten Fällen kann man die Verwendung des GOTO-Befehls vermeiden, wenn man das Programm anders strukturiert. Der folgende Code ist identisch mit dem Beispiel oben. Durch das Umkehren der Bedingung in der IF-Anweisung (IF A <= 0 statt IF A > 0) wird weder ein GOTO-Befehl noch Label benötigt. Zusätzlich wird das Programm übersichtlicher. |
IF A <= 0 THEN <Anweisungen 1> ' Werden ausgeführt wenn A nicht > 0 ist End IF <Anweisungen 2> ' Werden in jedem Fall ausgeführt |
|
Im Allgemeinen kann man das "umspringen" von Code mit GOTO durch eine IF-Anweisung ersetzen, wobei die Sprungbedingung negiert werden muss (d.h. aus = wird <>, aus < wird >= usw.). "Rückwärtssprünge" mit GOTO lassen sich meist durch eine REPEAT-UNTIL-Schleife ersetzen, wobei die Bedingung ebenfalls negiert werden muss.
Beispiel |
' Code mit GOTO LABEL marke1 INPUT "Geben sie eine positive Zahl ein"; A IF A <= 0 THEN GOTO marke1 |
' Code mit einer Schleife REPEAT INPUT "Geben sie eine positive Zahl ein"; A UNTIL A > 0 |
AbwärtskompatibilitätR-BASIC unterstützt auch die in vielen BASIC-Interpretern verwendete Kombination "GOTO Zeilennummer". Das kann die Übertragung fremder BASIC-Programme vereinfachen. Die "Zeilennummer" muss dabei explizit angegeben sein (z.B. "1000 CLS ...", siehe Beispiel). Sie sollten diese Variante in eigenen Programmen nicht verwenden.Beispiel: |
GOTO 1000 ' verzweigt das Programm nach unten .... ' Dieser Teil wird übersprungen 1000 CLS ... ' hier geht es dann weiter |
^2.5.5 Vorzeitiger ProgrammabbruchIn den meisten Fällen wird der Nutzer das Programm regulär über das Dateimenü beenden. R-BASIC bietet jedoch auch die Möglichkeit den Programmablauf vorzeitig per BASIC-Befehl zu beenden.EXITEXIT bricht die Programmausführung ab und schließt das Programm. Die Wirkung ist die gleiche als ob der Nutzer den Menüeintrag "Beenden" (oder "Verlassen") aus dem Dateimenü gewählt hat. EXIT kann an beliebiger Stelle im Programm stehen, auch in Schleifen und innerhalb von Unterprogrammen oder Action-Handlern.Syntax: EXIT Beispiel: |
IF X < 0 THEN EXIT |
ENDEND ist ein Befehl zur Wahrung der Abwärtskompatibilität zu anderen BASIC-Dialekten. In R-BASIC sollten Sie END nicht verwenden.END bricht den laufenden Programmteil ab, das Programm wird jedoch nicht geschlossen. END ist in klassischen BASIC-Programmen der üblich Weg, das Programm vorzeitig zu beenden. In R-BASIC bleibt ein Programm nach einem END-Befehl weiterhin funktionsfähig. END kann an beliebiger Stelle im Programm stehen, auch in Schleifen und innerhalb von Unterprogrammen oder Action-Handlern. Syntax: END Verwechseln Sie END nicht mit RETURN (siehe Kapitel 2.6, Unterprogramme). RETURN bewirkt, dass das Unterprogramm zurückkehrt, der auf den Aufruf des Unterprogramms (Sub oder Function) folgende Code wird abgearbeitet. END hingegen würgt den laufenden Handler komplett ab. Beispiel: |
IF X > 0 THEN END |
^ |