• QBasic - Schleifen

GOTO Endlosschleife

Zur Berechnung mehrerer Werte kann man eine sogenannte Endlos-Schleife (GOTO) verwenden. Ändere dazu das Programm power2.bas aus Lektion 1 wie folgt ab und speichere unter power3.bas:


REM
CLS
PRINT "PS", "Kilowatt"
PRINT
Hierher:
INPUT "Eingabe PS",p
LET k=p*0.735
PRINT p, k
GOTO Hierher

Die Zeile Hierher: ist eine sogenannte Sprungmarke (wichtig der Doppelpunkt am Ende). Trifft der Computer auf einen GOTO-Befehl, so prüft er die nachfolgende Angabe. Handelt es sich dabei um eine ihm bekannte Sprungmarke, so setzt er seine Berechnungen nicht wie sonst in der folgenden Zeile fort, sondern direkt nach der Sprungmarke. Dort steht aber der INPUT-Befehl, der eine erneute Eingabe fordert, dann folgt die Umrechnung von PS in Kilowatt. Schließlich trifft der Computer wiederum auf die GOTO-Zeile, springt wieder zur INPUT-Zeile, usw. Dieses Programm läuft solange, bis der Computer ausgeschaltet wird. Ein reguläres Programmende ist nicht möglich. Zum gewaltsamen Programm-Abbruch kann man aber auch die Tastenkombination Strg+C verwenden.

Für ein reguläres Ende braucht der Computer Bedingungen, unter denen er entscheiden kann, wann Schluss ist.

IF - THEN Entscheidung

Jedes der bisherigen Programme wird vom Computer linear abgearbeitet, d.h. von Zeile zu Zeile (auch bei Sprungmarken). In der Praxis wird jedoch oftmals verlangt, daß der Computer Entscheidungen treffen kann. Die dafür notwendige Anweisung hat die Form IF... THEN....
Tippe dazu folgendes Programm ein und speichere das Programm unter dem Namen raten1.bas

REM Zahlenraten
CLS

INPUT "Ratezahl: ",a : CLS
Weiter:
INPUT "Welche Zahl habe ich mir gemerkt? ", b
IF b = a THEN GOTO Hurra
IF b < a THEN PRINT "Zu klein, noch einmal"
IF b > a THEN PRINT "Zu groß, noch einmal"
GOTO Weiter
Hurra:
PRINT "Du bist super!" : PRINT "Die Zahl war ",a;"."

Ein Mitspieler gibt zunächst die Ratezahl ein (keine Dezimalzahlen!). Daraufhin wird der Bildschirm sofort gelöscht. Das Raten kann beginnen. Nach Eingabe einer Zahl beginnt das Programm die Ratezahl mit der Eingabe zu vergleichen:
Wenn die Zahlen gleich sind (IF b=a), dann gehe zur Marke Hurra (THEN GOTO Hurra), gib die Meldung aus und beende das Programm.
Wenn die Eingabe kleiner ist als die Ratezahl (IF b<a), dann gib eine entsprechende Meldung aus (THEN PRINT .) und setze den Programmablauf an der Stelle Weiter: fort (GOTO Weiter).
Wenn die Eingabe größer ist als die Ratezahl (IF b>a), dann gib eine entsprechende Meldung aus (THEN PRINT .) und setze den Programmablauf an der Stelle Weiter: fort (GOTO Weiter).

Nachteil des Programms ist es, daß man einen Mitspieler braucht, der die Ratezahl eingibt. Diesen Teil kann auch der Computer übernehmen. Mit Hilfe eines Zufallsgenerators können Zufallszahlen erzeugt werden (zufall.bas).


REM Zufall
RANDOMIZE TIMER : LET zaehler=1
Schleife:
PRINT TAB(5); RND; TAB(30); INT(6*RND+1)
LET zaehler=zaehler+1
IF zaehler<500 THEN GOTO Schleife
PRINT "Fertig"

Der Befehl RANDOMIZE TIMER setzt den Zufallsgenerator auf einen bestimmten Startpunkt (abhängig von der Einschaltzeit des Computers). In zwei Spalten werden dann Zufallszahlen ausgegeben. In Spalte 5 stehen Zahlen zwischen 0 und 0,999999999999 (mit RND), in Spalte 30 stehen Zahlen von 1 bis 6 (mit INT(6*RND+1). Sollen Lottozahlen (1 bis 49) erzeugt werden, wählt man INT(49*RND+1).

Das folgende Programm ermöglicht nur maximal 20 Rateversuche. Tippe das Programm ein und speichere dann das Programm unter dem Namen raten3.bas ab.


REM verbessertes Zahlenraten
CLS
PRINT "Zahlenraten"
PRINT "-----------"
PRINT
PRINT "Ich denke mir eine Zahl zwischen 1 und 1000, die es zu"
PRINT "erraten gilt."
PRINT
RANDOMIZE TIMER
LET zaehler = 0
LET cz = INT(RND(1) * 1000) + 1
Wiederhole:
LET zaehler = zaehler + 1
PRINT zaehler; ".Zahl: ";
INPUT "", rz
IF rz < cz THEN PRINT "zu klein"
IF rz > cz THEN PRINT "zu groß"
PRINT
IF zaehler < 20 and rz <> cz THEN GOTO Wiederhole
IF rz=cz THEN
PRINT "Gewonnen ..."
ELSE
PRINT "Verloren ..."
END IF

Das obige Programm wird beendet, wenn man die Zahl errät oder wenn man bereits 20 Zahlen eingegeben hat.
Die IF... THEN...-Anweisung kann um die ELSE-Anweisung erweitert werden. Die englischsprachichen Begriffe, die in BASIC für diese Möglichkeit verwendet werden, lassen sich auch leicht ins Deutsche übersetzen:

WENN die im folgenden formulierte Bedingung erfüllt ist,
DANN führe die hierstehende Anweisung aus,
SONST führe die hierstehende Anweisung aus.

Beachte: Erstreckt sich die IF...THEN...-Anweisung oder die IF...THEN...ELSE-Anweisung über mehrere Zeilen, so muß die Anweisung mit END IF abgeschlossen werden.

 

FOR ... NEXT - Schleife

Starte QBasic und schreibe folgendes einfaches Programm (addi1.bas), welches fünf eingegebene Zahl aufaddiert und dann die Summe ausgibt:


REM Addition 1
CLS
LET gesamt=0
INPUT "Zahl: ",a
LET gesamt=gesamt+a
INPUT "Zahl: ",a
LET gesamt=gesamt+a
INPUT "Zahl: ",a
LET gesamt=gesamt+a
INPUT "Zahl: ",a
LET gesamt=gesamt+a
INPUT "Zahl: ",a
LET gesamt=gesamt+a
PRINT gesamt

Da einige Programmzeilen wiederholt auftreten, können diese mit Bearbeiten - Kopieren und Bearbeiten - Einfügen erzeugt werden und müssen nicht jedesmal neu getippt werden. Starte das Programm, und addiere damit die Zahlen 23, 56, 78, 99 und 204. Die Summe ist: ................

Trotz der Erleichterung durch Kopieren / Einfügen kann das die richtige Programmierpraxis nicht sein. Bei fünf Zahlen mag das ja noch angehen, bei hundert oder tausend Zahlen jedoch nicht mehr. Es gibt einen viel besseren Weg. Man stellt eine Variable zaehler auf, die bis 5 zählt und dann das Programm über eine IF THEN Schleife anhält (addi2.bas):


REM Addition 2
CLS
LET gesamt=0
LET zaehler=1
Marke:
PRINT "Zahl";zaehler;": ";
INPUT a
LET gesamt=gesamt+a
LET zaehler=zaehler+1
IF zaehler<=5 THEN GOTO Marke
PRINT gesamt

Addiere mit diesem Programm die selben Zahlen wie zuvor und vergleiche die Summen. Die Anzahl der zu addierenden Zahlen läßt sich mit dieser Methode sehr leicht ändern, indem man
IF zaehler <= 5 ...
ändert zu
IF zaehler <= 100 ... .
Diese Zählweise ist so praktisch, daß es zwei eigene Befehle gibt: den FOR-Befehl und den NEXT-Befehl. Sie werden stets gemeinsam verwendet.
Die FOR...NEXT-Schleife kann immer dann eingesetzt werden, wenn die Anzahl der Wiederholungen schon im voraus feststeht.
Ändere das vorige Programm wie folgt ab. Dieses Programm (addi3.bas) leistet genau dasselbe wie das Programm Addition 2.


REM Addition 3
CLS
LET gesamt=0
FOR zaehler=1 TO 5
PRINT "Zahl";zaehler;": ";
INPUT a
LET gesamt=gesamt+a
NEXT zaehler
PRINT gesamt

In der FOR-Zeile wird der Anfangs- und der Endwert für die Zählvariable gesetzt. In der NEXT-Zeile wird die Zählvariable automatisch um 1 erhöht, wird geprüft, ob der Endwert schon erreicht wurde und falls nicht, wird der Programmteil zwischen FOR und NEXT erneut abgearbeitet.

Soll die Zählvariable um einen anderen als den voreingestellten Wert 1 erhöht werden, verwendet man den STEP-Zusatz. Was bewirkt das folgende Programm (folge1.bas)?


REM Schleife 1
CLS
FOR zaehler=1 TO 20 STEP 2
PRINT zaehler;", ";
NEXT zaehler
PRINT

Verwende anschließend auch andere STEP-Werte wie 3, 4, 8 oder 1.5. Beachte, daß auch Kommazahlen als STEP-Werte verwendet werden können und daß der Endwert durch die Zählvariable nicht genau getroffen werden muß.

Ändere das Programm 'Schleife 1' so ab, daß es das folgende Aussehen hat.


REM Schleife 2
CLS
FOR zaehler=10 TO 1
PRINT zaehler;", ";
NEXT zaehler
PRINT

Warum funktioniert das Programm nicht?


Füge an Zeile 3 des vorigen Programmes den Zusatz STEP -1 an und starte das Programm erneut. Speichere unter folge2.bas


REM Schleife 2
CLS
FOR zaehler=10 TO 1 STEP -1
PRINT zaehler;", ";
NEXT zaehler
PRINT

Das Programm gibt jetzt die Zahlen von 1 bis 10 in umgekehrter Reihenfolge korrekt aus.

 

DO ... LOOP ... UNTIL - Schleife

Diese Schleife rahmt einen Satz von Befehlen ein, welcher so oft durchlaufen wird, bis die Aussage wahr ist – also True ergibt. Hier einmal ein Beispiel (hallo.bas):

REM Hallo
CLS
INPUT "Bitte geben Sie eine Zahl ein: ", anzahl
DO

x = x + 1
PRINT "Hallo ("; x; ")"
LOOP UNTIL x = anzahl
END

Dieses Programm gibt das Wörtchen "Hallo" mit in Klammern geschriebener Zählvariable aus. Ist die Zählvariable so groß wie die eingegebene Zahl, endet das Programm.

Im folgenden Beispielprogramm (sterne.bas)werden erste Grafikbefehle verwendet:im Grafikmodus SCREEN 12 wird der Bildschirm in 640 mal 480 Bildpunkte (Pixel) aufgeteilt. Die obere linke Ecke hat die Koordinaten 0,0; die untere rechte Ecke die Koordinaten 639,479.
Ein Punkt kann gesetzt werden mit Hilfe des Befehls PSET (x,y),farbe.
LINE (a,b)-(x,y),5, B zieht ein Rechteck zwischen den Punkten (a,b) und (x,y) mit der Farbe 5.

REM Sterne
CLS
SCREEN 12
LINE (0, 0)-(639, 459), 15, B
RANDOMIZE TIMER
sterne = 0
maxSterne=5000
DO
sterne = sterne + 1
x = 2 + RND * 636
y = 2 + RND * 456
farbe = 1 + RND * 15
PSET (x, y), farbe
LOOP UNTIL sterne > maxSterne
END

Weiter gehts mit Unterprogrammen in Lektion3!


Aufgaben

  1. Ändere das Programm Zahlenraten (raten1.bas), indem du Zufallszahlen zwischen 1 und 100 berechnen läßt, und speichere das Programm unter raten2.bas
  2. Schreibe ein Programm, welches 6 Lottozahlen aus 49 Zahlen ausgibt. Speichere unter lotto.bas
  3. Erstelle ein Programm mit einer verschachtelten FOR NEXT Schleife, welches das kleine Einmaleins auf dem Bildschirm darstellt Speichere unter einmal.bas. Verwende bei der Bildschirmausgabe die Tabulatorfunktion!

 



... zurück zum Inhalt