Basic lernen (Einleitung, Vorbereitungen, Kapitel 1, 2, 3, 4, 5, 6)

Kontrollstrukturen, Sprunganweisung

Sie haben gelernt, den Benutzer Eingaben machen zu lassen, doch auswerten konnten wir sie bisher noch nicht. Was hier fehlt, sind sog. "Kontrollanweisungen". Sie überprüfen eine bestimmte Bedingung auf deren Wahrheit (trifft die Bedingung zu oder nicht) und führen je nach Ergebnis verschiedenen Quellcode aus. [Mehr dazu später] Kontrollstrukturen schließen jedoch nicht nur Kontrollanweisungen ein, sondern auch sog. "Schleifen". Diese dienen dazu, Quellcode kontrolliert oft zu wiederholen. Auch hier sind wieder Bedingungen wichtig. Beispiel: Addiere solange den Wert einer Variable und gib ihn danach aus, bis die Bedingung Variablenwert = 100 erfüllt ist. Also: +1 addieren, Wert ausgeben, +1 addieren, Wert ausgeben,... bis so oft 1 addiert wurde, dass der Wert der Variable, in der der Wert gespeichert ist, nun 100 beträgt. Dies ist nur eines von tausenden Anwendungsgebieten von Schleifen. [Mehr dazu später]

3.1; Kontrollanweisungen:

Eine Kontrollanweisung führt einen gewissen Anweisungsblock (dieser besteht aus einzelnen Programmierzeilen) nur unter bestimmten Bedingungen aus. Nehmen wir einmal an, es sollte ein Anweisungsblock nur dann ausgeführt werden, wenn 2 eingegebene Zahlen gleich sind. Also gibt der Benutzer 2 Zahlen ein, ich nehme einmal 2 und 2 an und danach zeigt das Programm "Zahlen gleich" auf dem Bildschirm an. Der Grund dafür ist, dass im Anweisungsblock die Zeile PRINT "Zahlen gleich" steht.

Nehmen wir noch einmal das Beispiel des Euroumrechners her. Ich habe den Quellcode so geschrieben, dass nur eine Umrechnung von Schilling (bzw. im 2. Beispiel DM) nach Euro möglich ist und nicht in umgekehrte Richtung. (Schilling bzw. DM nach Euro) Um die Umrechnung in beide Richtungen möglich zu machen, benötigen wir eine Kontrollanweisung, um die Eingabe des Benutzers auswerten zu können. Der Benutzer soll schließlich entscheiden, welche Art von Umrechnung er durchführen möchte.

In Basic haben wir 2 Arten von Kontrollanweisungen. Die eine, die IF-Anweisung führt nur bei Erfüllung einer Bedingung einen Anweisungsblock aus. Zusätzlich lässt sich auch eine Anweisungsblock bestimmen, der ausgeführt wird, wenn die Bedingung nicht erfüllt wird. Die zweite Anweisung, die Case-Anweisung überprüft einen Wert und führt je nach dessen Wert verschiedene Anweisungsblöcke aus. Mit der Case-Anweisung könnten wir z.B. folgende Überprüfung realisieren: Überprüfe eingegebenen Wert. Wenn dieser 1, dann zeige "Eins" am Bildschirm an, bei 2 "Zwei", bei 3 "Drei", bei 30 "Dreißig" und bei 1000000 "Welch eine große Zahl...". Man könnte die Case-Anweisung auch als "Erweiterte IF-Anweisung" bezeichnen, schließlich kann man sich mit der Case-Anweisung unter bestimmten Umständen durchaus einiges an Tipparbeit ersparen.

Tippen Sie das nächste Beispiel ein und lassen Sie es laufen.

CLS
PRINT "Geben Sie eine Zahl ein: ";
INPUT zahl
IF zahl = 2 THEN PRINT "Der Wert der Eingabe beträgt 2."

Lautet Ihre Eingabe nun 2, so zeigt das Programm "Der Wert der Eingabe beträgt 2." an. Der Grund dafür liegt in der letzten Anweisung. Schauen wir uns gleich die Syntax der IF-Anweisung im einfachsten Fall (dem obigen) an:

IF Bedingung THEN Anweisung

Die Bedingung ist hierbei ein boolescher Ausdruck. Bedenken Sie, dass ein boolescher Ausdruck entweder wahr (true) oder falsch (false) ist. Beachten wir beispielsweise das obige Beispiel. Hier steht als Bedingung zahl = 2. Dies können wir als Ganzes betrachtet als den Ausdruck bezeichnen. Ist der Wert der Variable zahl tatsächlich 2, so ist die Bedingung erfüllt. (true) Wäre jedoch der Wert der Variable zahl ein anderer (in dem Fall egal ob kleiner oder größer) so wäre die Bedinung nicht erfüllt und der Anwendungsblock würde darauf hin nicht ausgeführt werden.

Bitte bedenken Sie, dass sich die IF-Anweisung nicht auf den anderen Quellcode auswirkt. Die Anweisungen, die nach der IF-Anweisung folgen, werden auf jeden Fall ausgeführt. Egal, ob die Bedingung der IF-Anweisung erfüllt wird oder nicht.

Wollen Sie mehrere, als nur eine Anweisung ausführen lassen, müssen Sie folgendermaßen vorgehen:

IF Bedingung THEN
Anweisung 1
Anweisung 2
Anweisung 3
...
END IF

Wie man bereits an der Syntax erkennen kann, muss nach den Anweisungen lediglich ein END IF folgen.

Hängt man an die bisher beschriebene IF-Anweisung zusätzlich einen ELSE-Block an, kann man erreichen, dass auch ein anderer Anweisungsblock ausgeführt werden soll, sollte die Bedingung nicht erfüllt werden. Ändern wir das Beispiel mal folgendermaßen ab:

CLS
PRINT "Geben Sie eine Zahl ein: ";
INPUT zahl
IF zahl = 2 THEN
  PRINT "Der Wert der Eingabe beträgt 2."
ELSE
  PRINT "Der Wert der Eingabe beträgt NICHT 2!"
END IF

Im Gegensatz zu anderen Programmiesprachen ist die Sache in Basic nicht ganz einfach. Es gibt mehrere Möglichkeiten, den ELSE-Block anzuhängen.

Die minimalste Version sieht so aus:

IF Bedingung THEN Anweisung ELSE Andere Anweisung

Wird die Bedingung erfüllt, so wird die "Anweisung" (oben als solche bezeichnet) ausgeführt, anderenfalls die "Andere Anweisung" (wieder oben als solche bezeichnet). Beachten Sie, dass alles in einer Zeile steht! Wollen Sie die Anweisung auf mehrere Zeilen aufteilen (was ich Ihnen dringends empfehlen würde), so ist folgende Form nötig:

IF Bedingung THEN
Anweisung
ELSE
Andere Anweisung
END IF

Sie können natürlich auch mehrere Zeilen angeben, wie hier:

IF Bedingung THEN
Anweisung 1
Anweisung 2
Anweisung 3
...
ELSE
Andere Anweisung 1
Andere Anweisung 2
Andere Anweisung 3
...
END IF

Wieviele Anweisungen angegeben werden, ist natürlich vollkommen egal.

Damit wären die Möglichkeiten (fast) aller anderen Programmiersprachen ausgeschöpft. Basic bietet zusätzlich noch den folgenden Zusatz an:

IF Bedingung 1 THEN
Anweisung
ELSEIF Bedingung 2 THEN
Andere Anweisung
ELSE Wenn Bedingung 2 nicht erfüllt, diese Anweisung END IF

Der Einfachheit halber habe ich jeweils nur eine Anweisung angegeben. Der Vorgang läuft nun so ab: Ist die "Bedingung 1" (oben als solche bezeichnet) erfüllt, wird die "Anweisung" (oben als solche bezeichnet) ausgeführt. Ist die "Bedingung 1" allerdings nicht erfüllt, wird die "Bedingung 2" abgefragt. Ist diese erfüllt, wird die "Andere Anweisung" ausgeführt, ist die "Bedingung 2 allerdings nicht erüllt, wird stattdessen die Anweisung ausgeführt, die nach ELSE angegeben wurde.

Als eine erweiterte IF-Anweisung könnte man die CASE-Anweisung bezeichnen, der Syntax folgendermaßen aussieht:

SELECT CASE Variable
CASE Bedingung 1
  Anweisung 1
CASE Bedingung 2
  Anweisung 2
...
END SELECT

Statt bloß einer Anweisung können auch mehrere angegeben werden. Doch wozu benötigen wir nun die CASE-Anweisung? Zunächst einmal überprüft diese den Wert der angegebenen Variable. Nun folgen Überprüfungen: Ist die 1. Bedingung erfüllt, wird der dort angegebener Anweisungsblock ausgeführt. Ist die Bedingung nicht erfüllt, wird die nächste Bedingung überprüft usw. Es ist auch möglich, mehrere Bedingungen gleichzeitig anzugeben. Das nächste Beispiel soll das u.a. erläutern:

CLS
INPUT "Geben Sie eine Zahl ein: ", eingabe
SELECT CASE eingabe
CASE 1
  PRINT "Die Eingabe war eins."
CASE 2
  PRINT "Die Eingabe war zwei."
CASE 3,4
  PRINT "Der Wert der Eingabe war entweder drei oder vier."
CASE 5 TO 10
  PRINT "Die eingegebene Zahl ist im Bereich, der sich von fünf bis zehn erstreckt."
END SELECT

Ich habe bei diesem Beispiel übrigens auch Einrückungen im Quelltext verwendet. (dh. einfach ein paar Leerzeichen vor der Programmierzeile eingefügt) Dies sorgt für eine höhere Übersicht! Der Ablauft sieht nun so aus: Ist der Wert der Eingabe 1, so wird "Die Eingabe war eins." angezeigt, ist der Wert 2, dann "Die Eingabe war zwei.". Interessant ist die nächste Bedingung, genauer gesagt wurden zwei Bedingungen angegeben. (3 und 4) Ist der Wert der Eingabe entweder 3 oder 4, wird "Der Wert der Eingabe war entweder drei oder vier." angezeigt. Die nächste Bedingung bezeichnet einen ganzen Bereich, der sich von 5 (5 mit eingeschlossen) bis 10 (ebenso mit eingeschlossen) erstreckt. Liegt der Eingabewert irgendwo dazwischen, wird "Die eingegebene Zahl ist im Bereich, der sich von fünf bis zehn erstreckt." angezeigt.

Was jedoch, wenn Sie eine andere Zahl (0 oder größer als 10) oder gar ein nicht-numerisches Zeichen eingeben? In einem solchen Fall würde gar nichts angezeigt werden. Dem können wir Abhilfe schaffen. Dem nächsten Beispiel wurde ein CASE ELSE-Block hinzugefügt, dessen Anweisung angezeigt wird, wenn die anderen Bereiche die Eingabe nicht abdecken.

CLS
INPUT "Geben Sie eine Zahl zw. 1 und 10 ein: ", eingabe
SELECT CASE eingabe
CASE 1
  PRINT "Die Eingabe war eins."
CASE 2
  PRINT "Die Eingabe war zwei."
CASE 3,4
  PRINT "Der Wert der Eingabe war entweder drei oder vier."
CASE 5 TO 10
  PRINT "Die eingegebene Zahl ist im Bereich, der sich von fünf bis zehn erstreckt."
CASE ELSE
  PRINT "Was haben Sie denn da für 'nen Blödsinn eingegeben???"
END SELECT

3.2; Schleifen:

Eine Schleife dient dazu, um bestimmte Anweisungen so oft wiederholt auszuführen, bis eine bestimmte Bedingung erfüllt bzw. nicht erfüllt ist.

Es gibt in Basic mehrere Schleifen, wovon ich mit der FOR-Schleife aufgrund ihrer Einfachheit beginne. Die FOR-Schleife bietet dem Programmierer die Möglichkeit, Anweisungen kontrolliert oft ausführen zu lassen. Angenommen, ein Anweisungsblock soll 10 mal ausgeführt werden, so wäre dies eine gültige Bedingung, die der Programmierer angeben könnte.

Sehen wir uns gleich einmal die Syntax an:

FOR Zaehler = Von TO Bis STEP Schrittweite
Anweisung 1
Anweisung 2
Anweisung 3
...
NEXT Zaehler

Wie üblich ist es nicht zwingend notwendig, mehr als eine Anweisung im Anweisungsblock anzugeben. Der Zähler bezeichnet eine Variable, die "mitzählt", wie oft die Anweisungen bereits wiederholt wurden. Anstelle von "Von" und "Bis" stehen zwei Werte (bzw. 2 Variablen), die angeben, ab welcher Stelle zu zählen begonnen werden soll ("Von") und bis wohin gezählt werden soll. ("Bis") Die Schrittweite gibt an, um welchen Wert die Variable nach einem Durchlauf inkrementiert (inkrementieren = hinaufzählen) bzw. dekrementiert (dekrementieren = hinunterzählen) werden soll. STEP sowie die Angabe einer Schrittweite ist nicht unbedingt notwendig. Wird nichts angegeben, wird automatisch 1 angenommen.

Schauen wir uns dies einmal genauer anhand eines Beispiels an:

CLS
FOR i = 1 to 10 STEP 1
  PRINT i
NEXT i

Die Variable i ist hierbei die Zählervariable, ihre Aufgabe ist es, abzuspeichern, wie oft die Schleife bereits durchlaufen wurde. Zu Zählen begonnen wir bei 1, wird der Wert 10 erreicht (daher die Schleife 10 mal durchlaufen), endet die Ausführung der Schleife. STEP 1 gibt an, dass nach jedem Durchlauf, der Wert der Variable i um 1 erhöht werden soll. (1 addieren nach jedem Durchlauf) 10 mal wird also die Anweisung PRINT i ausgeführt. Das Ergebnis davon ist, dass das Programm von 1 bis 10 zählt!

Nun wollen wir das Programm von 10 bis 1 zählen lassen. Um dieses Rückwärtszählen bewerkstelligen zu können, müssen wir lediglich die Bedingungen und den STEP-Wert verändern. Das sieht nun so aus:

CLS
FOR i = 10 to 1 STEP -1
  PRINT i
NEXT i

Mit jedem Schleifendurchlauf wird nun der Wert der Variable um 1 dekrementiert.

Die nächste Schleife, mit der wir uns befassen, ist die WHILE-Schleife. Der Anweisungsblock dieser Schleife, wird solange ausgeführt, solange (= while) die Bedingung erfüllt ist.

WHILE Bedingung
Anweisung 1
Anweisung 2
Anweisung 3
...
WEND

Das obige Beispiel so verändert, dass die WHILE-Schleife zum Einsatz kommt:

CLS
i = 1
WHILE i <= 10
  PRINT i
i = i + 1
WEND

Ich bin der Ansicht, dass dieses Beispiel nur mehr eine kurze Erläuterung benötigt. Neu für Sie dürfte der Operator <= sein. Die Bedeutung ist kleiner oder gleich. Im obigen Beispiel heißt dies nun folgendes: Wiederhole die Schleife solange der Wert der Variable i kleiner oder gleich 10 ist. Wichtig ist, dass nach der PRINT-Anweisung eine Zeile folgt, die den Wert der Variable inkrementiert. Ansonsten würde der Wert der Variable immer 1 bleiben, und die Schleife würde bis in alle Ewigkeit ausgeführt werden. Eine Endlosschleife also...

Tipp: Übrigens können Sie die Ausführung eines Programmes jederzeit mit STRG+UNTBR abbrechen - sollten Sie z.B. mal wieder eine Endlosschleife programmieren...

Die letzte Form der Schleifen, mit denen wir uns beschäftigen, sind DO-LOOP-Schleifen. Im einfachsten Fall ...

DO
Anweisung 1
Anweisung 2
Anweisung 3
...
LOOP

... spricht man von einer Endlosschleife. Mittlerweile müssten Sie ausreichend Basic-Wissen haben, um zu verstehen, was die obige Syntax aussagt. Auf eine nähere Erläuterung verzichte ich deshalb.

Jedoch sind hiermit die Möglichkeiten dieses Schleifentyps noch lange nicht ausgeschöpft. Es gibt 4 weitere Möglichkeiten:

Möglichkeit 1; DO-LOOP-WHILE

DO
Anweisung 1
Anweisung 2
Anweisung 3
...
LOOP WHILE Bedingung

Solange die Bedingung erfüllt ist, wird diese Schleife ausgeführt. Diese Bedingung steht jedoch am Schluss der Schleife, das hat zur Folge, dass die Schleife mindestens einmal ausgeführt wird, egal ob die Bedingung erfüllt ist oder nicht.

Möglichkeit 2; DO-LOOP-UNTIL

DO
Anweisung 1
Anweisung 2
Anweisung 3
...
LOOP UNTIL Bedingung

Diese Schleife wird solange ausgeführt, solange die Bedingung NICHT erfüllt ist. Oder anders ausgedrückt: Die Schleife wird solange ausgeführt, bis die Bedingung erfüllt wird!

Möglichkeit 3; DO-WHILE-LOOP

DO WHILE Bedingung
Anweisung 1
Anweisung 2
Anweisung 3
...
LOOP

Diese Schleife funktioniert nach dem selben Prinzip, wie die WHILE-(WEND-)Schleife. Die Schleife wird solange ausgeführt, solange eine Bedingung erfüllt ist.

Möglichkeit 4; DO-UNTIL-LOOP

DO UNTIL Bedingung
Anweisung 1
Anweisung 2
Anweisung 3
...
LOOP

Wir hatten bereits die DO-LOOP-UNTIL-Schleife behandelt. Diese führt einen Anweisungsblock solange aus, bis eine Bedingung erfüllt ist. Allerdings wird der Anweisungsblock bei der DO-LOOP-UNTIL-Schleife mindestens einmal ausgeführt, da die Bedingung am Schluss steht. Bei der DO-UNTIL-LOOP-Schleife, mit der wir es hier zu tun haben, steht jedoch die Bedingung am Anfang. Das hat zur Folge, dass der Anweisungsblock auch überhaupt nicht ausgeführt werden würde, wäre die Bedingung gleich beim Beginn (dem Eintritt in die Schleife) erfüllt.

Ein abschließendes Beispiel ist zur näheren Erläuterung meiner Ansicht nach nicht notwendig. Jedoch ist es dringend notwendig, das Erlernte auszuprobieren!

3.3; Sprunganweisung:

Ich habe mir überlegt, ob ich nicht einfach die Erklärung des GOTO-Befehls unterschlagen sollte. Der GOTO-Befehl erlaubt es, Sprünge innerhalb des Quellcodes durchzuführen. Das hat zur Folge, dass der entstehende Code sehr unübersichtlich wird. Sollte im Quellcode ein Fehler stecken, so ist dieser meist nur sehr schwer zu finden. Trotz alldem wird der GOTO-Befehl von Basic-Programmierern sehr häufig eingesetzt, obwohl es durchaus auch anders ginge.. [Wie lernen Sie im nächsten Kapitel, wenn wir uns mit Funktionen und SUBs beschäftigen]

Damit Sprünge durchgeführt werden können, muss an die Stelle im Quellcode, zu der gesprungen werden soll, eine Sprungmarke gesetzt werden. Eine Sprungmarke steht immer alleine in einer Zeile. Jede Sprungmarke benötigt einen Bezeichner (Namen) und wird mit einem Doppelpunkt abgeschlossen. Das sieht dann in etwa so aus:

Sprungmarke:

Wurde die Sprungmarke gesetzt, kann nun mit GOTO in diese Zeile gesprungen werden:

GOTO Sprungmarke

Ein kleines Beispiel habe ich auch hier parat:

CLS
anfang:
PRINT "Dies ist die erste Programmierzeile."
GOTO ende
PRINT "Diesen Text werden Sie wohl nie angezeigt bekommen..."
ende:
PRINT "Dies ist die (vor)letzte Programmierzeile."
GOTO anfang:

Testen Sie Ihre Programmierkenntnisse. Versuchen Sie herauszufinden, wie der Programmablauf aussieht, ohne das Beispiel ausprobiert zu haben. Wenn Sie sich eine Vorstellung davon gemacht haben, probieren Sie das Beispiel aus und überprüfen Sie, ob Ihre Vorstellungen mit der Praxis übereinstimmen.

Erläuterung: In der zweiten Programmierzeile steht eine Sprungname, die den Bezeichner "anfang" trägt. Dass sich diese Sprungmarke an Zeile 2 befindet, hat vorerst noch keine Auswirkungen auf die Programmausführung. Kurz gesagt: Eine Sprungmarke stört nicht, bei der normalen Quellcodeausführung wird sie einfach ignoriert. Nur, wenn mittels GOTO ein Sprung durchgeführt wird, ist sie notwendig. Die nächste Zeile (PRINT ...) zeigt einen Text auf dem Bildschirm an. In der darauffolgenden Zeile erfolgt ein Sprung zur Sprungmarke "ende". Es wird folglich wiederum ein Text angezeit. Zum Schluss erfolgt ein Sprung in die zweite Programmierzeile. Und das Ganze beginnt wieder von vorne ... Eine Endlosschleife ist also das Resultat des Beispiels. Übrigens: Mit STRG+UNTBR können sie die Programmausführung abbrechen.


Vorheriges Kapitel Nächstes Kapitel