4. Bildschirmausgabe
Nach diesen doch recht theoretischen Vorüberlegungen wollen wir nun aber mit den ersten Programmen beginnen. Eine der wichtigsten Aufgaben von Computerprogrammen ist die Verarbeitung von Daten: Das Programm liest Daten ein, verarbeitet sie und gibt das Ergebnis aus. Zunächst werden wir uns die Bildschirmausgabe ansehen.
4.1 Der PRINT
-Befehl
Der Befehl PRINT
wurde in der Einführung bereits vorgestellt. Mit ihm ist es möglich, einen Text, auch Zeichenkette oder String genannt, auf dem Bildschirm auszugeben:
PRINT "Hallo FreeBASIC-Welt!" SLEEP
Der abschließende Befehl SLEEP
dient übrigens dazu, das Programm so lange geöffnet zu halten, bis eine Taste gedrückt wurde. Nach Ausführung des letzten Befehls ist das Programm beendet; das Programmfenster schließt sich damit wieder. Ohne dem SLEEP
würde zwar der Text angezeigt, danach aber das Programm sofort geschlossen werden, sodass der Benutzer keine Möglichkeit mehr hat, den Text zu lesen. SLEEP
verhindert das sofortige Beenden und erlaubt es dem Benutzer, die Ausgabe anzusehen.
Der Text, der ausgegeben werden soll, wird in "doppelte Anführungszeichen" gesetzt (das Zeichen mit dem ASCII-Code 34; auf den meisten westeuropäischen Tastaturen über [Shift]+[2]
erreichbar). Wenn der Text selbst ein doppeltes Anführungszeichen enthalten sollen, müssen Sie an die entsprechende Stelle einfach nur zwei dieser Zeichen hintereinander setzen — der Compiler weiß dann, dass die Zeichenkette nicht endet, sondern ein Anführungszeichen geschrieben werden soll.
PRINT "Wilkommen bei meinem ""tollen"" Programm!" SLEEP
Wilkommen bei meinem "tollen" Programm!
Im Gegensatz dazu werden Zahlen ohne Anführungszeichen geschrieben. FreeBASIC kann so auch als Taschenrechner „missbraucht“ werden.
PRINT 2 PRINT 5 + 3 * 7 SLEEP
2
26
Wie Sie sehen, hält sich das Programm an die Rechenregel „Punkt vor Strich“. Vielleicht sollte noch kurz erwähnt werden, dass sich in der Programmierung der Stern *
als Malzeichen eingebürgert hat, während als Divisionszeichen der Schrägstrich /
verwendet wird.
Potenzen werden mit dem Zeichen ^
geschrieben. Außerdem können auch Klammern eingesetzt werden, jedoch sind für Berechnungen nur runde Klammern erlaubt. In Quelltext 4.1l werden zur Veranschaulichung einige Berechnungen durchgeführt.
Normalerweise wird die Ausgabe nach jedem PRINT
in einer neuen Zeile fortgesetzt. Um mehrere Ausgaben (z. B. ein Text und eine Rechnung) direkt nacheinander zu erhalten, dient der Strichpunkt ; als Trennzeichen. Steht der Strichpunkt ganz am Ende der Anweisung, so findet die nächste PRINT
-Ausgabe in derselben Zeile statt.
Auch das Komma , kann als Trennzeichen eingesetzt werden. Dabei wird jedoch ein Tabulator gesetzt; die Ausgabe setzt nicht direkt hinter der letzten Ausgabe fort, sondern an der nächsten Tabulatorposition.
PRINT "Addition: 5 + 2 ="; 5+2 ' zwei Ausgaben hintereinander PRINT "Subtraktion: 5 - 2 ="; 5-2 PRINT "Multiplikation: 5 * 2 ="; ' die naechste Ausgabe findet in PRINT 5*2 ' derselben Zeile statt PRINT "Division: 5 / 2 ="; 5/2 PRINT "Exponent: 5 ^ 2 ="; 5^2 PRINT ' Leerzeile ausgeben PRINT "gemischt:", "4 + 3*2 ="; 4 + 3*2 ' Komma zum Tabulator-Einsatz PRINT , "(4 + 3)*2 ="; (4 + 3)*2 ' geht auch zu Beginn der Ausgabe SLEEP
Addition: 5 + 2 = 7
Subtraktion: 5 - 2 = 3
Multiplikation: 5 * 2 = 10
Division: 5 / 2 = 2.5
Exponent: 5 ^ 2 = 25
gemischt: 4 + 3*2 = 10
(4 + 3)*2 = 14
Noch einmal zusammengefasst: Zeichenketten bzw. Strings müssen in Anführungszeichen gesetzt werden, Berechnungen stehen ohne Anführungszeichen. Nach der Ausgabe wird in der folgenden Zeile fortgesetzt, außer der Zeilenumbruch wird durch einen Strichpunkt oder ein Komma unterdrückt. Dabei dient der Strichpunkt dazu, die Ausgabe an der aktuellen Stelle fortzusetzen. Das Komma setzt bei der nächsten Tabulatorstelle fort.
Achtung: An der Ausgabe der Divisionsaufgabe können Sie erkennen, dass als Dezimaltrennzeichen kein Komma verwendet wird, sondern ein Punkt. Wenn Sie selbst Dezimalzahlen einsetzen wollen, müssen Sie ebenfalls den Punkt als Trennzeichen verwenden. |
4.2 Ausgabe von Variablen
4.2.1 Deklaration von Variablen
Um sich innerhalb des Programmes Werte merken zu können, werden Variablen verwendet. Variablen sind Speicherbereiche, in denen alle möglichen Arten von Werten abgelegt werden können. Man kann sie sich gewissermaßen wie „Schubladen“ vorstellen, in die der gewünschte Wert hineingelegt und wieder herausgeholt werden kann. Dabei kann jede „Schublade“ nur eine bestimmte Art von Werten speichern. Es gibt beispielsweise INTEGER
-Variablen, in denen Ganzzahlen (also ohne Nachkommastellen) abgelegt werden können, während STRING
-Variablen Zeichenketten speichern. Jeder Variablentyp kann nur die zugehörige Art an Daten speichern — in einer Zahlenvariablen kann keine Zeichenkette abgelegt werden und in einer STRING
-Variablen keine Zahl (wohl aber eine Zeichenkette, die eine Zahl repräsentiert). Welche Variablentypen zur Verfügung stehen und wo die genauen Unterschiede liegen, wird in Kapitel 6 erklärt.
Bevor eine Variable verwendet werden kann, muss dem Programm zunächst bekannt gemacht werden, dass die gewünschte Variable existiert. Man spricht dabei vom Deklarieren der Variable. Üblicherweise wird dazu der Befehl DIM
verwendet.
DIM variable1 AS INTEGER DIM AS INTEGER variable2
Der oben stehende Code deklariert zwei INTEGER-Variablen mit den Namen variable1
bzw. variable2
. Beide genannten Schreibweisen sind möglich; welche Sie verwenden, hängt zum einen vom persönlichen Geschmack ab, hat zum anderen aber auch praktische Gründe: Sollen mehrere Variablen deklariert werden, dann kann das oft mit einem einzigen Befehl erledigt werden.
DIM variable1 AS INTEGER, variable2 AS SHORT, variable3 AS STRING
deklariert drei Variablen unterschiedlichen Typs auf einmal. Wenn alle drei Variablen demselben Datentyp angehören, bietet sich hier die zweite Schreibweise an:
DIM AS INTEGER variable1, variable2, variable3
Dies ist wesentlich kürzer, setzt jedoch voraus, dass der Datentyp aller drei Variablen gleich ist. Wollen Sie drei Variablen unterschiedlichen Typs gleichzeitig deklarieren, dann müssen Sie auf die erste Schreibweise zurückgreifen. Die Bedeutung der einzelnen Datentypen folgt in den nächsten Kapiteln.
4.2.2 Wertzuweisung
Wertzuweisungen erfolgen über das Gleichheitszeichen =
DIM AS INTEGER variable variable = 3
variable
bekommt hier den Wert 3 zugewiesen — zu einem späteren Zeitpunkt des Programmes kann dieser Wert wieder ausgelesen und verwendet werden. Da man einer neuen Variablen sehr oft gleich zu Beginn einen Wert zuweisen muss, gibt es eine Kurzschreibweise für Deklaration und Zuweisung:
DIM AS INTEGER variable1 = 3, variable2 = 10 DIM variable3 AS INTEGER = 8, variable4 AS INTEGER = 7
In den beiden Zeilen werden je zwei INTEGER
-Variablen deklariert und sofort mit einem Wert belegt. Beachten Sie bitte die Schreibweise: die Zuweisung steht immer am Ende, also in der zweiten Zeile erst nach dem Variablentyp.
Bevor die verschiedenen Datentypen besprochen werden, muss noch geklärt werden, welche Variablennamen überhaupt verwendet werden dürfen. Ein Variablenname darf nur aus Buchstaben (a-z, ohne Sonderzeichen wie Umlaute oder ß), den Ziffern 0-9 und dem Unterstrich _ bestehen. Allerdings darf das erste Zeichen keine Ziffer sein. Außerdem kann nur ein Name benutzt werden, der noch nicht in Verwendung ist. Beispielsweise können keine FreeBASIC-Befehle als Variablennamen verwendet werden, aber selbstverständlich können auch nicht zwei verschiedene Variablen denselben Namen besitzen.
Obwohl als Variablenname eine Bezeichnung wie gzyq8r
zulässig ist, werden Sie später, wenn Sie auf diesen Namen stoßen, wohl keine Ahnung mehr haben, was die Variable für eine Bedeutung hat. Sie sollten daher lieber Namen wählen, mit denen Sie auf den Inhalt der Variable schließen können. Wollen Sie z. B. das Alter des Benutzers speichern, bietet sich der Variablenname alter
weitaus mehr an als der Name gzyq8r
. Die Verwendung von „sprechenden Namen“ ist eines der obersten Gebote des guten Programmierstils!
Einer Variablen kann auch der Wert einer anderen Variablen zugewiesen werden, oder auch ein Wert, der mithilfe anderer Variablen berechnet wird.
DIM AS INTEGER var1 = 3, var2 = 10 ' Deklaration DIM AS INTEGER mittelwert = (var1 + var2) / 2 ' Deklaration mit Wertzuweisung var1 = var1 + 1 ' Wert um 1 erhoehen
In der letzten Zeile sehen Sie sehr schön, dass es sich um eine Zuweisung und nicht um eine mathematische Gleichung handelt. Mathematisch gesehen ist var1=var1+1
keine sinnvolle Aussage. Bei der Zuweisung dagegen berechnet das Programm den Wert der rechten Seite und weist das Ergebnis der Variablen auf der linken Seite zu.
(Nachdem ich jetzt eindrücklich die Verwendung sprechender Namen angemahnt habe, kommt gleich im Anschluss ein Beispiel mit so nichtssagenden Namen wie var1
und var2
… Allerdings haben diese Variablen in den kurzen Codeabschnitten tatsächlich keine besondere Bedeutung, weshalb ich die aus Platzgründen möglichst kurz gewählten Namen zu entschuldigen bitte.)
4.2.3 Wertvertauschung
Um den Wert zweier Variablen (z. B. var1
und var2
) zu vertauschen, kann nun nicht einfach der zweiten Variablen der Wert der ersten zugewiesen werden und umgekehrt — mit der ersten Zuweisung geht nämlich der ursprüngliche Wert der zweiten Variablen verloren. Zur Veranschaulichung sehen Sie in den folgenden Codeschnipsel im Kommentar jeweils die Wertbelegungen, welche die Variablen nach Ausführung der Zeile besitzen. Außer der Wertzuweisungen machen diese „Progrämmchen“ allerdings nichts, weshalb Sie beim Ausführen des Codes nichts sehen würden.
' das funktioniert nicht ... DIM AS INTEGER var1 = 3, var2 = 10 ' var1 = 3; var2 = 10 var2 = var1 ' var1 = 3; var2 = 3 var1 = var2 ' var1 = 3; var2 = 3
Stattdessen muss der Wert der ersten Variable zwischengespeichert werden, damit er anschließend weiter zur Verfügung steht. Das lässt sich mit einer zusätzlichen temporären Variablen erreichen.
' das funktioniert dagegen: DIM AS INTEGER var1 = 3, var2 = 10, temp ' var1 = 3; var2 = 10; temp = 0 temp = var2 ' var1 = 3; var2 = 10; temp = 10 var2 = var1 ' var1 = 3; var2 = 3; temp = 10 var1 = temp ' var1 = 10; var2 = 3; temp = 10
Wie Sie sehen, wurden die Werte von var1
und var2
jetzt korrekt vertauscht. Allerdings ist die Vorgehensweise recht aufwändig. FreeBASIC stellt daher einen Befehl zur Verfügung, der die Angelegenheit deutlich schneller regelt:
' Werte vertauschen mit SWAP DIM AS INTEGER var1 = 3, var2 = 10 ' var1 = 3; var2 = 10 SWAP var1, var2 ' var1 = 10; var2 = 3
4.2.4 Ausgabe des Variablenwertes
Um nun den Wert einer Variablen auszugeben, wird sie einfach in eine PRINT
-Anweisung eingefügt. Sie kann auch für Berechnungen verwendet werden.
DIM vorname AS STRING, alter AS INTEGER vorname = "Otto" alter = 17 PRINT vorname; " ist"; alter; " Jahre alt." PRINT "In drei Jahren wird "; vorname; alter+3; " Jahre alt sein." SLEEP
Otto ist 17 Jahre alt.
In drei Jahren wird Otto 20 Jahre alt sein.
In den Zeilen 4 und 5 wird die Ausgabe jeweils aus mehreren Teilen zusammengesetzt. Die Zeichenketten, welche exakt wie angegeben auf dem Bildschirm erscheinen sollen, sind wieder in Anführungszeichen gesetzt. Die Variablen stehen genauso wie die Zahlenwerte ohne Anführungszeichen.
Der aufmerksame Leser wird bemerkt haben, dass bei der Ausgabe vor den Zahlen — und ebenso vor dem Wert einer Zahlenvariablen — ein Leerzeichen eingefügt wird. Genauer gesagt handelt es sich dabei um den Platzhalter für das Vorzeichen der Zahl. Ein positives Vorzeichen wird nicht angezeigt und bleibt daher leer. Bei negativen Zahlen dagegen wird dieser Platz durch das Minuszeichen belegt. Wenn Sie in Quelltext 4.2 für alter
den Wert -17
eingeben, werden Sie sehen, dass die zusätzlichen Leerzeichen wegfallen.
4.3 Formatierung der Ausgabe
Das Komma im PRINT
-Befehl ist zur Formatierung der Ausgabe ganz nett, aber nicht sehr flexibel. Um die Ausgabe an einer bestimmten Stelle fortzusetzen, gibt es mehrere Möglichkeiten.
4.3.1 Direkte Positionierung mit LOCATE
Mit dem Befehl LOCATE
wird eine Zeile und eine Spalte angegeben, an die der Cursor gesetzt wird. Die nächste Textausgabe beginnt an dieser Position. Die Nummerierung der Zeilen und Spalten beginnt mit 1 — die Anweisung LOCATE 1, 1
setzt den Cursor also in das linke obere Eck. Die beiden durch Komma getrennten Zahlen werden Parameter genannt.
LOCATE 1, 20 ' erste Zeile, zwanzigste Spalte PRINT "Der LOCATE-Befehl" LOCATE 2, 20 ' zweite Zeile, zwanzigste Spalte PRINT "=================" LOCATE 4, 1 ' Beginn der vierten Zeile PRINT "Mit dem Befehl LOCATE wird der Cursor positioniert." SLEEP
Der LOCATE-Befehl
=================
Mit dem Befehl LOCATE wird der Cursor positioniert.
Es ist auch möglich, nur einen der beiden Parameter anzugeben. Mit LOCATE 5
beispielsweise wird der Cursor in die fünfte Zeile gesetzt, während die aktuelle Spalte nicht verändert wird. Wenn umgekehrt nur die Spaltenposition geändert werden soll, fällt der erste Parameter weg, das Komma muss jedoch stehen bleiben. Ansonsten könnte der Compiler Zeilen- und Spaltenparameter ja nicht auseinanderhalten. Das oben verwendete Beispiel könnte damit auch folgendermaßen aussehen, ohne dass sich die Ausgabe ändert:
LOCATE 1, 20 ' erste Zeile, zwanzigste Spalte PRINT "Der LOCATE-Befehl" ' Nun befindet sich der Cursor am Anfang der zweiten Zeile LOCATE , 20 ' in die zwanzigste Spalte setzen PRINT "=================" ' Nun befindet sich der Cursor am Anfang der dritten Zeile LOCATE 4 ' in die vierte Zeile setzen PRINT "Mit dem Befehl LOCATE wird der Cursor positioniert." SLEEP
4.3.2 Positionierung mit TAB
und SPC
Im Gegensatz zu LOCATE
werden die Befehle TAB
und SPC
innerhalb der PRINT
-Anweisung gesetzt:
PRINT "Spalte 1"; TAB(20); "Spalte 20"
Die Befehle bewirken Ähnliches wie ein im PRINT
eingebautes Komma, nämlich das Vorrücken zu einer bestimmten Spaltenposition, nur dass diese Position frei gewählt werden kann. Beachten Sie auch, dass der Parameter in diesem Fall in Klammern geschrieben werden muss.
TAB
rückt den Cursor an die angegebene Stelle vor. Es bestehen also Ähnlichkeiten zu LOCATE
mit ausgelassenem ersten Parameter. Beachten Sie jedoch, dass tatsächlich vorgerückt wird. Notfalls wechselt der Cursor in die nächste Zeile.
PRINT "Zeile 1, Spalte 1"; TAB(5); "Zeile 2, Spalte 5"
Da sich der Cursor nach der ersten Ausgabe bereits in Spalte 18 befindet, muss er, um die Spalte 5 zu erreichen, in die zweite Zeile vorrücken.
SPC
rückt den Cursor um die angegebene Zeichenzahl weiter. Der Unterschied zu TAB
besteht also darin, dass TAB(20)
den Cursor genau in die Spalte 20 setzt, während SPC(20)
den Cursor um 20 Zeichen weiter rückt (also z. B. von Spalte 15 nach Spalte 35).
PRINT "Spalte 1"; TAB(20); "Spalte 20" PRINT "Spalte 1"; SPC(20); "Spalte 29"
Bei Bedarf wird in die nächste Zeile gewechselt. SPC(400)
etwa wird mehrere Zeilen weiter rücken — bei einer Konsolenbreite von 80 Zeichen werden es fünf Zeilen sein, um die der Cursor nach unten rutscht.
Unterschiede zu QuickBASIC: Im Gegensatz zu QuickBASIC werden in FreeBASIC die übersprungenen Zeichen nicht mit Leerzeichen überschrieben. Der bereits vorhandene Text bleibt erhalten. |
4.3.3 Cursor-Position ermitteln: POS
und CSRLIN
Um umgekehrt herauszufinden, wo sich der Textcursor gerade befindet, helfen die beiden Befehle POS
(POSition) und CSRLIN
(CurSoR LINe). POS
gibt die Spalte zurück, in der sich der Cursor im Augenblick befindet, und CSRLIN
die aktuelle Zeile.
Es sollte nicht überraschen, dass eine Abfrage der Cursor-Position innerhalb einer PRINT
-Anweisung das Ergebnis beeinflussen kann. Im folgenden Quelltext wird das anhand zweier PRINT
-Anweisungen demonstriert. In der ersten Anweisung in Zeile 1 wird POS
erst abgefragt, nachdem der vorherige Text bereits ausgegeben wurde und sich der Cursor in der 44. Spalte befindet. Dagegen wird die Cursorposition für die zweite Ausgabe zuerst gespeichert und dann dieser gespeicherte Wert ausgegeben.
PRINT "Der Cursor befindet sich in Zeile"; CSRLIN; ", Spalte"; POS DIM AS INTEGER zeile = CSRLIN, spalte = POS PRINT "Der Cursor befindet sich in Zeile"; zeile; ", Spalte"; spalte SLEEP
Der Cursor befindet sich in Zeile 1, Spalte 44
Der Cursor befindet sich in Zeile 2, Spalte 1
4.3.4 Farbige Ausgabe
Nun wollen wir etwas Farbe ins Spiel bringen. Im Konsolenfenster stehen uns 16 Farben zur Verfügung. Wir können jeweils die Vorder- und Hintergrundfarbe des Textes auf eine dieser Farben setzen. Dazu dient der Befehl COLOR
, dem zwei Parameter mitgegeben werden können, nämlich der Farbwert der Vordergrundfarbe und der Farbwert der Hintergrundfarbe.
COLOR 1, 4
setzt die Vordergrundfarbe auf den Wert 1 und die Hintergrundfarbe auf den Wert 4.
Die Farbwerte nützen selbstverständlich nur etwas, wenn man weiß, welche Farben sich dahinter verbergen. Es handelt sich dabei um die CGA-Farbwerte (siehe Tabelle 4.1). Das obige Beispiel würde also beim nächsten PRINT
einen blauen Text auf rotem Hintergrund ausgeben.
Farbnr. | Farbe | Farbnr. | Farbe |
---|---|---|---|
0 |
Schwarz |
8 |
Grau |
1 |
Blau |
9 |
Hellblau |
2 |
Grün |
10 |
Hellgrün |
3 |
Cyan |
11 |
Hell-Cyan |
4 |
Rot |
12 |
Hellrot |
5 |
Magenta |
13 |
Hell-Magenta |
6 |
Braun |
14 |
Gelb |
7 |
Hellgrau |
15 |
Weiß |
Tabelle 4.1: Farbwerte (Konsole)
COLOR 1, 4 PRINT "Dieser Text ist in blauer Schrift auf rotem Hintergrund." COLOR 4, 1 PRINT "Dieser Text ist in roter Schrift auf blauem Hintergrund." COLOR 14 PRINT "Dieser Text ist in gelber Schrift auf blauem Hintergrund." COLOR , 0 PRINT "Dieser Text ist in gelber Schrift auf schwarzem Hintergrund." SLEEP
Wie Sie sehen, können Sie auch einen der beiden Parameter auslassen — in diesem Fall wird nur der angegebene Wert geändert und der andere beibehalten. Außerdem sollte Ihnen aufgefallen sein, dass die gewählte Hintergrundfarbe nur an den Stellen angezeigt wird, an denen Text ausgegeben wurde. In der Regel wird man sich aber wünschen, dass der Hintergrund im kompletten Fenster die gleiche Farbe besitzt, also z. B. ein blaues Fenster mit gelber Schrift. Hierzu kann der Befehl CLS
dienen.
4.3.5 Bildschirm löschen mit CLS
CLS
ist eine Abkürzung von CLear Screen und löscht den Inhalt des Fensters. Mehr noch: das Fenster wird vollständig auf die eingestellte Hintergrundfarbe gesetzt. Dazu muss erst die Hintergrundfarbe über COLOR
eingestellt und anschließend der Bildschirm mit CLS
gelöscht werden.
COLOR 6, 1 CLS PRINT "Der ganze Bildschirm ist jetzt blau." PRINT "Die Schrift wird gelb dargestellt." SLEEP
Das Löschen des Fensterinhalts fällt in diesem Beispiel nicht ins Gewicht, weil das Fenster ja bisher noch nichts enthält. Das einzig Interessante ist im Augenblick das Setzen des Fensterhintergrunds.
Bitte bedenken Sie jedoch beim Einsatz von Farben, dass manche Farbkombinationen für einige Menschen sehr schwer lesbar sind! Außerdem sollte man es, wie bei allen Spezialeffekten, nicht übertreiben — oft gilt: weniger ist mehr. In der Testphase dürfen Sie sich natürlich erst einmal austoben.
4.4 Fragen zum Kapitel
Am Ende der meisten Kapitel werden Sie einige Fragen und/oder kleine Programmieraufgaben finden, mit denen Sie das bisher Gelernte überprüfen können. Die Antworten erhalten Sie im Anhang A.
-
Welche Bedeutung besitzt innerhalb einer
PRINT
-Anweisung der Strichpunkt, welche Bedeutung besitzt das Komma? -
Was bedeutet das Komma in anderen Anweisungen?
-
Wann werden Anführungszeichen benötigt, wann nicht?
-
Welche Zeichen sind für einen Variablennamen erlaubt?
-
Was versteht man unter sprechenden Namen?
-
Was sind die Unterschiede zwischen
TAB
undSPC
?
Und noch eine kleine Programmieraufgabe für den Schluss:
Schreiben Sie ein Programm, das den gesamten Hintergrund gelb färbt und dann in roter Schrift (ungefähr) folgende Ausgabe erzeugt:
Mein erstes FreeBASIC-Programm
==============================
Heute habe ich gelernt, wie man mit FreeBASIC Text ausgibt.
Ich kann den Text auch in verschiedenen Farben ausgeben.
Anschließend soll das Programm auf einen Tastendruck warten.