Zwar können Sie jetzt bereits korrekte Anweisungsfolgen bilden, in denen Sie auch Zuweisungen mit deklarierten Variablen durchführen können, jedoch fehlen Ihnen noch Möglichkeiten zur Ausgabe der Ergebnisse oder zum Einlesen variabler Werte. In diesem Abschnitt werden deshalb die Gegenstücke zu den Befehlen INPUT und PRINT in BASIC vorgestellt.
Pascal unterscheidet sich von BASIC durch ein standardmäßig vorhandenes Konzept zur Formatierung der Ausgabe und etwas vielseitigere Eingabemöglichkeiten, die eine Zeilenstruktur der Benutzereingaben berücksichtigen können.
In Ihrem ersten Programm (Bild 6) trat bereits die Anweisung WRITELN auf. Syntaktisch gesehen ist WRITELN ein vordefinierter Name, dem in Klammern Parameter, das sind Ausdrücke getrennt durch Kommata, folgen können.
Die einfachste Form einer Ausgabeanweisung hat folgende Struktur:
WRITE(Ausdruck)
Es genügt also, den auszugebenden Wert in Klammern hinter dem vordefinierten Namen WRITE anzugeben. Dadurch wird das Ergebnis des Ausdruckes berechnet und am Bildschirm ausgegeben:
PROGRAM WRITEBEISPIEL(OUTPUT); VAR ZWISCHENERGEBNIS: REAL; GANZEZAHL : INTEGER; BEGIN WRITE('Dies ist ein Beispiel '); WRITE('für Bildschirmausgaben:'); WRITE(20 * 3); WRITE(1 / 3); ZWISCHENERGEBNIS:= SIN(0.5) + COS(0.5); GANZEZAHL:= 3; WRITE(ZWISCHENERGEBNIS); WRITE(GANZEZAHL); WRITE(300 > 15); WRITE(1, 2, 3, 4, 5, GANZEZAHL-4); END.
Wenn Sie dieses Programm ausführen lassen, werden Sie feststellen, daß aufeinanderfolgende WRITE-Anweisungen die Ausgaben ohne Zwischenraum hintereinanderstellen. Die Ausgabe hängt vom Typ des Ausdruckes ab:
WRITE(3) 3 WRITE(3.1) 3.10000000E+00 WRITE(3.0) 3.00000000E+00
WRITE(300 > 15) TRUE WRITE(SIN(3)=COS(3)) FALSE
Zusammefassend läßt sich also sagen, daß Sie die Ergebnisse jedes beliebigen Ausdruckes oder die Inhalte beliebiger Variablen jederzeit mit der WRITE-Anweisung darstellen können. Nicht nur für den Anfänger ist das Einfügen von WRITE-Anweisungen eine willkommene Möglichkeit, den Programmablauf am Bildschirm zu verfolgen.
Speziell bei der Darstellung von Zahlen möchte man die Ausgabe oft formatiert vornehmen. Generell erfolgt eine Formatierung in Pascal durch die Angabe einer Feldgröße. Die Philosophie besteht darin, dem auszudruckenden Wert eine feste Anzahl an Stellen einzuräumen, innerhalb derer das Ergebnis rechtsbündig gedruckt wird. Betrachten Sie als Beispiel die Ausgabe der folgenden Tabelle:
Name |Vorname |arbeitslos| Kinder | Gehalt ----------------------------------------------- Meier | Otto | FALSE | 0 | 3000.00 ........ |....... |......... | ...... |........
Für die Spalten Name, Vorname, arbeitslos, Kinder und Gehalt sollen dabei die durch Punkte markierten Stellen (8, 7, 9, 6 und 8 Zeichen) bedruckt werden, während vor dem senkrechte Strich jeweils ein Leerzeichen steht.
In Pascal würde man die obige Zeile durch die Angabe einer Feldgröße nach einem Doppelpunkt hinter den zu druckenden Werten formatieren, wobei eine Person mit einem Gehalt von 0.0 als arbeitslos bezeichnet wird:
PROGRAM TABELLE(OUTPUT); VAR KINDER: INTEGER; GEHALT: REAL; BEGIN WRITELN(' Name |Vorname |arbeitslos| Kinder | Gehalt'); WRITELN('-----------------------------------------------'); KINDER:=0; GEHALT:= 3000.0; WRITE('Meier' : 8);WRITE(' |'); WRITE('Otto' : 7);WRITE(' |'); WRITE(Gehalt = 0.0 : 9);WRITE(' |'); WRITE(Kinder : 6);WRITE(' |'); WRITE(Gehalt : 8 : 2); WRITE(' |'); WRITELN; END.
Formal läßt sich die Wirkung der Angabe einer Feldgröße folgendermaßen beschreiben: Die Feldgröße definiert eine Mindestanzahl an Zeichen, die bei der Ausgabe gedruckt wird. Ist die Darstellung des auszugebenden Wertes kleiner als die Feldgröße, so wird der Wert rechtsbündig in einem Feld der genannten Größe ausgegeben. Die Feldgröße wird ignoriert, falls die Ausgabe zu lang ist.
Interessanterweise kann die Feldgröße auch durch einen Ausdruck angegeben werden, der ein ganzzahliges Ergebnis liefert. Damit ist also eine variable Feldgröße möglich.
Beispiel: (Die Striche stellen Leerzeichen dar, die zum Erreichen der Feldgröße eingefügt werden)
WRITE (3*4 : 5); ___12 (rechtsbündig) WRITE('***': 5); __*** (rechtsbündig) WRITE(3.0 : 5); 3.00000000E+00 (Feld war zu klein) WRITE('xxx': 0); xxx (Feld war zu klein) WRITE(12 : 3+2); ___12 (3+2 = 5)
In dem Beispielprogrammen WRITEBEISPIEL und TABELLE wurden bereits weitergehende Möglichkeiten der Ausgabe in Pascal verwendet:
Beliebig viele direkt aufeinanderfolgende WRITE-Befehle können nämlich immer zu einem einzigen zusammengefaßt werden, wobei man die Parameter durch Kommata trennt. Die Werteliste hinter der WRITE-Anweisung kann sich natürlich auch über mehrere Quelltextzeilen erstrecken:
WRITE('Meier' : 8, ' |', 'Otto' : 7, ' |', Gehalt = 0.0 : 9, ' |', Kinder : 6, ' |', Gehalt : 8 : 2, ' |');
Die letzte Ausgabe dieser Anweisung besitzt zwei Formatierungsparameter, die durch Doppelpunkte getrennt sind. Dadurch können reelle Zahlen auch im Festpunktformat dargestellt werden. Der erste Formatierungsparameter bestimmt wiederum die Feldgröße, während der zweite Parameter die Anzahl der Nachkommastellen definiert. Deshalb wird im obigen Beispiel das Gehalt rechtsbündig in einem Feld aus 8 Zeichen ausgegen, wobei 2 Nachkommastellen gedruckt werden.
Im Programmbeispiel TABELLE wurden insgesamt drei Bildschirmzeilen ausgegeben. Um die Ausgabe am Anfang der Folgezeile fortzusetzen, existiert die Anweisung WRITELN (write line). So werden mit der Anweisungsfolge
WRITELN; WRITELN; WRITELN
drei Leerzeilen gedruckt. Für WRITELN sind die gleichen Parameter wie bei der Anweisung WRITE zulässig. Dabei entspricht die Ausgabe
WRITELN(Ausdruck, Ausdruck, ...)
folgender Anweisungsfolge:
WRITE(Ausdruck, Ausdruck, ...); WRITELN
Es wird also zusätzlich am Ende der Ausgabe ein Zeilenvorschub ausgeführt (s. auch Beispielprogramm TABELLE).
Die Eingabe ist in Pascal völlig symmetrisch zur Ausgabe organisiert. Jedoch entfallen die Formatierungsparameter, so daß es nicht wie in FORTRAN oder COBOL möglich ist, eine Eingabezeile in Felder fester Länge einzuteilen.
Haben Sie im Vereinbarungsteil wie im letzten Kapitel beschrieben Variablen deklariert, so können Sie auch Werte vom Bildschirm einlesen. Dabei erfolgt die Eingabe zeilenweise.
PROGRAM PQFORMEL(INPUT, OUTPUT); VAR P,Q,W,A: REAL; BEGIN WRITE('P Q ='); READ(P); READ(Q); READLN; W:= SQRT(P * P / 4 - Q); A:= - P / 2; WRITELN('X1=', A+W); WRITELN('X2=', A-W); END.
Mit diesem Programm können Sie Nullstellen der gemischtquadratischen Funktion
0 = X * X + P * X + Q
bestimmen. Der Benutzer gibt die Werte P und Q vor, zu denen das Programm die Nullstellen X1 und X2 berechnen soll. Falls Sie sich noch an Ihren Mathematikunterricht erinnern, werden Sie auch wissen, daß nicht immer eine (reelle) Lösung existiert. Dieser Fall wird durch das Programm nicht überprüft, so daß es in diesem Fall versuchen würde, eine Quadratwurzel aus einer negativen Zahl zu berechnen.
Während Sie im Programm die Zuweisungen und die Ausgabeanweisung mit WRITELN bereits verstehen können, sind die Eingabeanweisungen READ und READLN Ihnen noch nicht geläufig. Eine Eingabe erfolgt mit der Anweisung READ, gefolgt von dem Namen einer deklarierten Variablen:
READ (Variablenname)
Der Benutzer wird mit blinkendem Cursor zur Eingabe aufgefordert. Er kann dann eine beliebige Folge von Zeichen eingeben. Schließt er die Eingabe mit der RETURN-Taste ab, so beginnt der Computer mit der Auswertung des Inhaltes der eingegebenen Zeile. Dabei bearbeitet er die Zeile sequentiell von links nach rechts.
Im Augenblick soll nur die Eingabe von Zahlen und Zeichen untersucht werden. Das Einlesen von Strings wird in Abschnitt 2.9.2 beschrieben.
Wie bei der Ausgabe können auch zwei aufeinanderfolgende READ-Anweisungen zu einer einzigen zusammengefaßt werden. Die beiden folgenden Zeilen liefern also dieselbe Eingabe:
READ(P); READ(Q) READ(P, Q);
Die Parameterliste einer READ-Anweisung kann demnach beliebig lang sein. Die Zahlen müssen vom Benutzer bei der Eingabe durch mindestens ein Leerzeichen oder einen Zeilenwechsel getrennt werden:
PROGRAM READVIEL(INPUT,OUTPUT); VAR A,B,C,D,E: INTEGER; BEGIN READ(A,B,C,D,E); WRITELN('EINGELESEN WURDEN FOLGENDE ZAHLEN:'); WRITE(A:4; B:4, C:4, D:4, E:4); END.
Für dieses Programm sind also folgende Eingaben möglich:
30 33 44 77 0 (RETURN-Taste)
oder
30 33 44 (RETURN-Taste) 77 (RETURN-Taste) 0 (RETURN-Taste)
Gibt man zu viele Werte ein,
30 33 44 77 0 1234 (RETURN-Taste)
so lesen die READ-Anweisungen bis zum Leerzeichen hinter der Zahl 0. Eine nachfolgende READ-Anweisung würde die Zahl 1234 lesen. Möchte man jedoch den Rest einer Eingabezeile ignorieren, so verwendet man den Befehl READLN (read line). Ohne weitere Parameter überliest er alle Zeichen bis zum Ende der laufenden Eingabezeile. So wurde im Beispielprogramm PQFORMEL folgende Anweisungsfolge verwendet:
READ(P); READ(Q); READLN
Gibt der Benutzer nämlich zu viele Werte (also mehr als 2) ein, so werden die überflüssigen Eingaben durch READLN überlesen und die nächste Eingabe wird am Anfang der Folgezeile erwartet. Wie bei WRITELN läßt sich eine solche Folge von READ- und READLN- Anweisungen zu einem Befehl zusammenfasssen:
READLN(P, Q);
Aufgaben
1. Damit Sie sich einen praktischen Überblick über die vielen verschiedenen Möglichkeiten zur Ein- und Ausgabe verschaffen können, sollten Sie die Beispiele aus dem Text am Computer ausprobieren. Dabei dürfen Sie jedoch die Deklaration der Variablen nicht vergessen. Wählen Sie verschiedene Ausdrücke und Variablen und verändern Sie die Spaltenbreite im Programm TABELLE.
2. Ändern Sie das Programm PQFORMEL so, daß die Werte für P und Q vom Benutzer in zwei aufeinanderfolgenden Zeilen eingelesen werden, und die Ausgabe folgendermaßen formatiert wird:
P = ........ Q = ........ X1 = 999999999.99 X2 = 999999999.99
3. Schreiben Sie ein Programm, das den Text Überschrift in einem Feld aus N Zeichen zentriert druckt. Das Feld soll durch zwei Sterne links und rechts begrenzt werden. Dabei soll der Benutzer die Zahl N an der Tastatur eingeben können:
N = 30 *..........ÜBERSCHRIFT.........* N = 20 *.....ÜBERSCHRIFT....*
Hinweis: Die Idee besteht darin, zunächst zu berechnen, wieviele Leerzeichen links und rechts eingefügt werden müssen. Die Anzahl der Leerstellen speichern Sie in zwei Variablen (LINKS und RECHTS) und benutzen anschließend folgende Anweisungen:
PROGRAM CENTER(INPUT,OUTPUT); VAR N, LINKS, RECHTS: INTEGER; BEGIN (* Hier müssen Sie N einlesen *) (* Hier berechnen Sie LINKS und RECHTS *) WRITELN('*', ' ': LINKS, 'ÜBERSCHRIFT', ' ': RECHTS, '*'); END.
4. Es werden vom Benuter folgende drei Zeilen eingegeben:
1 2 3 4 5 6 7 8 9 10 11 12
Programmieren Sie drei Anweisungsfolgen, die folgende Werte lesen:
Sie müssen also geeignete READ- und READLN-Anweisungen verwenden, die die übrigen Werte überlesen.
5. Ist Ihnen die genaue Wirkung der Feldgröße für reelle Zahlen noch unklar, so sollten Sie ein wenig mit folgendem Programm experimentieren (detaillierte Regeln für die Ausgabe finden sich übrigens nochmals in der Dokumentation in Abschnitt 4.4.4.5):
PROGRAM WRITEREAL(INPUT,OUTPUT); VAR R: REAL; FELDGROESSE: INTEGER; NACHKOMMA : INTEGER; BEGIN READLN(R, FELDGROESSE, NACHKOMMA); WRITELN('!', R: FELDGROESSE : NACHKOMMA, '!'); END.
6. Experimentieren Sie mit Ausdrücken, Anweisungsfolgen und den Ein- und Ausgabebefehlen! Schreiben Sie eigene kleine Programme, um ein Gefühl für Ausdrücke in Pascal zu bekommen!
Sollten Sie keine eigenen Ideen haben, können Sie sich an der folgenden kleinen Liste orientieren: Berechnung von Zinsen und Zinseszinsen, Berechnung der Fläche von Kreisen und Ellipsen, des Volumens von Kugeln und Kegeln. Berechnung des Logarithmus zur Basis 10. Vergleichen Sie
SIN(X) / COS(X) mit TAN(X)
Wie groß sind die Rechenfehler des Computers bei der Gleichung
SQR(SIN(X)) + SQR(COS(X)) = 1 ?
Wie berechnet man die Umkehrfunktion von SIN(X)? Eine Lösung findet sich übrigens im BASIC-Handbuch.