Die Elemente von QBAsIC, die ganz neue Konzepte einführen, wie Funktionen, Datentypen und Dateioperationen werden wir nicht in diesem, sondern in den nächsten Kapiteln behandeln.
CLS PRINT "Taschenrechner" PRINT "--------------" start: INPUT "Geben Sie zwei Zahlen ein: ", a, b PRINT "Summe: "; a + b PRINT "Differenz: "; a - b PRINT "Produkt: "; a * b PRINT "Verhältnis: "; a / b IF (a <> -1) GOTO startDie Sprungmarken sind ein Riesenvorteil, da "GOTO start" wesentlich aussagekräftiger ist, als "GOTO 1023".
Was wir hier auch gleich noch sehen: Der Befehl zum Bildschirmlöschen heisst hier "CLS", nicht "SCRCLR".
IFWas aber, wenn wir im Fall, dass die Bedingung wahr ist, eine ganze Menge machen wollten? Natürlich können wir die Befehle alle mit Doppelpunkten hinter das THEN packen, aber so richtig toll war das auch nicht:THEN
IF antwort$="j" THEN INPUT "Gib noch was ein:";b$:FOR i=1 TO LEN(b$):IF mid$(b$,i,1)="?" THEN b$=LEFT$(b$,i-1)+RIGHT$(b$,LEN(b$)-i-1):NEXT I: PRINT b$:GOTO 1234 ....(Diese Zeile würde ausserdem einen Syntaxfehler verursachen, weil man innerhalb einer Doppelpunktsequenz nicht nocheinmal einen IF-Befehl bringen kann.) Die andere Möglichkeit ist, sich mit vielen GOTO's zu helfen, die die Übersicht aber auch nicht gerade erleichtern:
IFAlles klar?THEN GOTO marke1 IF THEN GOTO marke2 ... GOTO marke3 marke2: ... GOTO marke3 marke1: ... marke3: ...
Der IF-Befehl in QBASIC/Visual Basic hat schon den vollen Umfang des If's der strukturierten Programmierung:
IFAn Stelle von "...THEN ... ELSEIF ... ELSE ... END IF
Das Ganze funktioniert also so: Falls Bedingung1 zutrifft, dann
führe den Block
Man muss nicht immer alle Teile dieser langen IF-Anweisung angeben. Man kann auch das ELSEIF oder ELSE weglassen. Es ginge also auch
IFOder eben:THEN ... END IF
IFAlle Klarheiten beseitigt? Machen wir noch ein einfaches Übungsbeispiel:THEN ... ELSE ... END IF
INPUT "Geben Sie ein Zahl ein: ",a IF a=1 THEN PRINT "Das ist das Doppelte: ",a*2 PRINT "Das ist das Vierfache: ",a*4 ELSEIF a=2 THEN PRINT "Das ist das Dreifache: ",a*3 PRINT "Das ist das Sechsfache: ",a*6 ELSE PRINT "Das ist weder 1 noch 2" END IFUnd noch ein etwas raffinierteres Beispiel: Hier enthält der erste Block hinter dem IF selbst nochmal ein IF mit Block:
CLS PRINT "Seltsamer Rechner" PRINT "--------------" start: INPUT "Geben Sie eine Zahl ein: ", a INPUT "Wollen Sie wissen, was die Haelfte ist? (j/n)", o$ IF (o$ = "j) THEN b = a / 2 PRINT "Die Haelfte ist: "; b ELSE PRINT "Wollen Sie wissen, was ein Viertel ist? (j/n)", o$ IF (o$ = "j") THEN c = a / 4 PRINT "Ein Viertel ist: "; c END IF END IF GOTO startWie Sie sehen, empfiehlt es sich, die Blöcke nach rechts einzurücken. Immer alle Zeilen, die zu einem Block gehören, sind gleichweit eingezogen. Dadurch kann man die Blöcke mit dem Auge leicht erkennen.
Ein wichtiges Extra bei der FOR-Schleife ist allerdings die EXIT-Anweisung. Mit dieser Anweisung bricht man eine FOR-Schleife vorzeitig ab. Dadurch können wir uns auch hier ein GOTO sparen.
Variante ohne EXIT:FOR i=1 TO 100 INPUT "Geben Sie eine Zahl ein: ",x IF x=0 THEN GOTO nachschleife PRINT 1/x NEXT i nachschleife: ...
Variante mit EXIT:
FOR i=1 TO 100 INPUT "Geben Sie eine Zahl ein: ",x IF x=0 THEN EXIT FOR PRINT 1/x NEXT i ...
WHILE-Möglichkeit:
DO WHILE... LOOP
DO-Möglichkeit:
DO ...Es gibt sogar noch zwei andere Möglichkeiten, aber die erwähne ich hier nicht, weil sie erstens programmiertechnisch keinen Vorteil bieten, also nur quasi ein Duplikat der anderen beiden Möglichkeiten darstellen (man nennt sowas auch: "Redundanz": Die beiden anderen Möglichkeiten sind redundant). Und weil sie zweitens kein Äquivalent in den Profisprachen der Pascal- und C-Familien haben. Hier gibt es jeweils nur drei Schleifentypen: FOR, WHILE und REPEAT UNTIL (bzw. DO WHILE).LOOP UNTIL
Die DO WHILE-LOOP-Möglichkeit ist also zur einfachen WHILE-Schleife identisch, bis auf die Möglichkeit, bei die WHILE-LOOP-Schleife mit einem EXIT DO abzubrechen.
Bei der DO-LOOP UNTIL-Möglichkeit wird zuerst der Anweisungsblock ausgeführt und dann geprüft. Ist die Bedingung wahr, dann wird die Schleife abgebrochen, hier also ein weiterer Unterschied zur WHILE-Schleife, wo eine wahre Bedingung zur Fortsetzung der Schleife führt.
Anwendungsbeispiel:
'Suche-Funktion INPUT "Geben Sie einen String ein: ", a$ INPUT "Geben Sie ein Wort ein, das im String gesucht werden soll:", such$ alen = LEN(a$) slen = LEN(such$) i = 1 found = 0 DO WHILE (NOT (found = 1)) AND (i <= alen - slen + 1) found = 1 FOR j = 1 TO slen a1$ = MID$(a$, i + j - 1, 1) s1$ = MID$(such$, j, 1) IF UCASE$(a1$)<>UCASE$(s1$) THEN found=0 NEXT j IF found = 0 THEN i = i + 1 LOOP IF (found = 1) THEN PRINT "Wort an Stelle "; i; " gefunden" ELSE PRINT "Wort wurde nicht gefunden" END IFWir hätten dieses Beispiel auch mit einer einfachen WHILE-Schleife formulieren können, da wir hier nirgends die Schleife abbrechen müssen.
Abgesehen von den Schleifen haben sich beim obigen Beispiel zwei weitere Neuerungen eingeschlichen: Das Hochkomma in der ersten Zeile und die Funktion UCASE$(). Das Hochkomma ist eine Alternative zu REM: Bei QBASIC/ Visual Basic empfiehlt sich, nur noch das Hochkomma als Kommentar zu benutzen, da so der Kommentar viel leichter vom eigentlichen Programmtext zu unterscheiden ist.
UCASE heisst "UpperCASE" und wandelt einen String in Grossbuchstaben um. Das Gegenstück dazu ist LCASE$(), welches - unschwer zu erraten - einen String in Kleinbuchstaben umwandelt. Durch die Umwandlung in Grossbuchstaben ist unsere Suchfunktion unabhängig von Gross- und Kleinschreibung. Jetzt wissen Sie, wie die Suchefunktion von Textverarbeitungsprogrammen programmiert ist! Nicht schwer, oder?
ende=0 WHILE (ende=0) CLS PRINT "Ihr Spiele-Menü:" PRINT "1. Vier gewinnt" PRINT "2. 17 und 4" PRINT "3. Formel 1" PRINT "4. Superhirn" PRINT "5. Millionärsshow" PRINT "6. Ende" PRINT COLOR 14,0 INPUT "Ihre Wahl: ",a IF a=1 THEN GOSUB viergewinnt ELSEIF a=2 THEN GOSUB 17und4 ELSEIF a=3 THEN GOSUB formel1 ELSEIF a=4 THEN GOSUB superhirn ELSEIF a=5 THEN GOSUB millionär ELSEIF a=6 THEN ende=1 WENDDen letzten Teil ab INPUT... kann man mit SELECT-Befehl so schreiben:
INPUT "Ihre Wahl: ",a SELECT CASE a CASE 1 GOSUB viergewinnt CASE 2 GOSUB 17und4 CASE 3 GOSUB formel1 CASE 4 GOSUB superhirn CASE 5 GOSUB millionär CASE 6 ende=1 END SELECTHier bringt das nicht wirklich Vorteile gegenüber IF. Wenn man allerdings sehr viele mögliche Werte berücksichtigen muss, die sich nur auf wenige Entscheidungszweige verteilen, dann kann der SELECT-Befehl einiges an Übersicht bringen. Ein
SELECT CASE a CASE 1,4,6,10,18 b=1 CASE 2,3,12,13,17 b=2 CASE 5,7,8,9,11 b=3 CASE ELSE b=4 END SELECTist doch erheblich übersichtlicher als ein
IF a=1 OR a=4 OR a=6 OR a=10 OR a=18 THEN b=1 ELSE IF a=2 OR a=3....Damit ist die Syntax von SELECT eigentlich auch schon erklärt:
SELECT CASE Variable CASE Werteliste1 ......heisst: Wenn "Variable" einen Wert der Werteliste1 annimmt, (Werte durch Komma getrennt), dann führe den Anweisungsblock hinter dem entsprechenden CASE aus. Entsprechend die anderen CASE-Teile. Es kann, muss aber kein CASE ELSE folgen. Dessen Anweisungsblock wird durchlaufen, falls kein Wert einer der Wertelisten "gepasst" hat.CASE Werteliste2 ... CASE ELSE ... END CASE
CLS FOR i = 0 TO 15 COLOR i, 0 PRINT "hhhhhhhhhhhhhhhhhh" REM INPUT a$ NEXT i CLS FOR i = 0 TO 15 COLOR 15, i PRINT "hhhhhhhhhhhhhhhhhh" REM INPUT a$ NEXT i FOR i = 0 TO 15 COLOR 15, i CLS INPUT a$ NEXT i END
12398.463723 183262.12 -28322.34762E00 usw.Für eine Rechnung wünschen wir uns die Zahlen rechtsbündig und auf exakt zwei Nachkommastellen gerundet.
Zunächstmal ist das eine sehr gute
Übung: Schreiben Sie ein Programm, dass die im Array zahlen() gespeicherten Beträge rechtsbündig und auf zwei Nachkommastellen gerundet auf dem Bildschirm ausgibt!
Wenn Sie nicht weitergkommen sein sollten, hier ein Hinweis auf den Lösungsweg:
Es ist also nicht so, dass wir das Problem mit C16-BASIC nicht hätten lösen können. Aber so nett das Austüfteln solcher kleinen Lösungen ist - wenn man nur noch damit beschäftigt ist und nicht mehr mit der eigentlich zu lösenden Aufgabe, macht's auch keinen Spass mehr und man kommt nicht mehr vorwärts.
Daher gilt ganz allgemein: Je umfangreicher der Satz an mitgelieferten Routinen (Unterprogrammen, Befehlen, Ressourcen - darunter können Sie vorläufig dasselbe verstehen) eines Entwicklungssystems ist, desto
Ein gutes Beispiel einer solchen mitgelieferten Ressource ist der PRINT USING- Befehl. Er benutzt einen Extra-String, mit dem angegeben werden kann, in welchem Format die folgenden Zahlen oder Strings ausgegeben werden sollen, d.h. mit wieviel Stellen vor und nach dem Komma, rechts- oder linksbündig die Zahl angezeigt werden soll. Deshalb heisst dieser Extrastring - nicht nur in QBASIC, auch in der wichtigen Sprache C gibt es so etwas - Formatstring.
Der String gibt zunächst die Länge des Felds an, in dem die Zahl ausgegeben werden soll.
"#####" z.B. gibt jede Zahl in einem fünf Zeichen langen Feld aus und zwar rechtsbündig. (Eine
Option für linksbündige Ausgabe gibt es nicht.)
FOR i=80 TO 89 PRINT USING "##########";i NEXT iergibt dann die Ausgabe
80 81 82 83 84 85 86 87 88 89Jedes #-Zeichen steht also für eine Ziffer oder - falls die Zahl nicht so lang ist - für ein führendes Leerzeichen. Mit einem Dezimalpunkt kann angegeben werden, auf wieviel Stellen gerundet werden soll:
Wenn man dem String ein Plus voranstellt, druckt es die Zahl immer mit führenden Vorzeichen:
FOR i=80 TO 89 PRINT USING "+##########";i NEXT iergibt dann die Ausgabe
+80 +81 +82 +83 +84 +85 +86 +87 +88 +89
Wenn man es hintenanstellt ("##########+") druckt PRINT USING das Vorzeichen hinter die Zahl.
Auch für Strings kann man die Länge des Ausgabefelds definieren. Hierzu schreibt man einen String mit der Länge des Ausgabefeldes aus Leerzeichen und führendem und abschliessendem Backslash. "\ \" z.B. sind 6 Leerzeichen plus die Backslashes=8 Zeichen langes Ausgabefeld. Ist der String länger, so werden nur die die ersten acht Zeichen davon ausgegeben, allgemein: Nur soviel Zeichen, wie der Formatstring lang ist.
Ganze Syntax: PRINT USING <Formatstring>Wert1;Wert2;
Im Formatstring von PRINT USING gibt's noch weitere Optionen, die aber nicht so interessant sind, zumindest nicht für Nicht-Bewohner der USA, da diese eher USA-spezifisch sind (Ausgabe des Dollarzeichens, zifferntrennenden Kommatas etc.). Wenn Sie neugierig sind: Schauen Sie in der Online-Hilfe von QBASIC die komplette Syntax nach!