Von Thomas Grasel

Vorwort der Redaktion: Mit der Dezem-
ber-Ausgabe hat sich leider unser
Mitarbeiter Christoph Bach von seinem
XL/XE verabschiedet und sich aus
beruflichen Gründen dem PC zugewendet.
Von nun an wird Thomas Grasel diesen
Kurs fortsetzen.


Hallo,

ich möchte euch zu einer neuen Runde
des Pascal-Kurses begrüßen.
Zunächst einmal die Vorraussetzungen:
Ich programmiere Pascal zur Zeit in
Kyan-Pascal 1.1 und suche nach einer
neueren Version.

Als erstes möchte ich noch einmal die
Unterschiede von Basic und Pascal
betonen. Beide Sprachen sind schon
ziemlich alt. Pascal entstand um 1970!!
in der Schweiz. Das sie heute, in
leicht veränderter Form, immer noch
verwendet wird zeigt das sie etwas
besonderes sein muß.

Pascal ist keine Sprache mit der man
leicht schöne Spiele programmieren
kann! Dafür ist sie nicht gedacht. Das
erkennt man sehr leicht an ihrem
Befehlsschatz. Da gibt es kein
GRAPHICS, POSITION, GOTO, RND usw. Aber
die Länge des Compilers, zeigt das
Pascal doch einiges können muß. Und
dies ist im Bereich der 'Datenver-
waltung' und mathematischer An-
wendungen.

An dieser Stelle könnte ich noch viel
tiefer in die Materie einsteigen, aber
das würde mit Sicherheit den Rahmen
dieses Kurses sprengen. Deshalb wer
noch gänzlich unbelastet nun mit Pascal
anfängt, sollte in eine der vielen
Büchereien gehen und ein Buch über
STANDART oder USCD-PASCAL ausleihen.
Allein das flüchige Durchlesen bringt
schon einmal einen Überblickt über die
Fähigkeiten von Pascal. Ansonsten gilt
wie immer "probieren geht über
studieren". Also nehmt euch die bei-
liegenden Programme und spielt einfach
damit herum!

Ich will generell versuchen nicht
seitenweise Befehle 'trocken' zu
erklären sondern sie nach und nach
anhand von Beispielprogrammen ein-
zuführen und dort zu erklären. Nun aber
noch ein paar Tips am Anfang:

Programmiert sauber, d.h. einrücken,
möglichst in Modulen (Proceduren)
arbeiten usw. sonst verliert ihr bei
längeren Programmen schnell die
Übersicht.

Vergeßt die Semikolons nicht, sonst
jongliert ihr ständig zwischen Editor
und Compiler.

Wer einen Rechner mit mehr als 64k hat
sollte Pascal auf die RAMDISK kopieren
und auch die eigenen Programme darauf
speichern. Natürlich ab und zu auf die
Floppy Zwischenspeichern. Wenn man mit
einem DOS arbeitet das zwischen
physikalischen und logischen Laufwerken
unterscheiden kann, dann sollte man D1
auf die RAMDISK und z.B. D2 auf die
Bootfloppy zeigen lassen (Das erspart
das lästige eingeben der 8 bei jeder
Diskettenoperation).

Leider erkennt der Compiler aus Platz-
gründen nicht alle Fehler. Daher bei
unsinnigen Ausgaben erst mal nach
Flüchtigkeitsfehlern suchen.



Aber nun zum ersten Programm.

Wenn möglich druckt es bitte aus denn
so kann man es dann viel besser lesen.
Auf dem Bildschirm gehen halt viele
Zeilen über den Rand hinaus (sorry!)
Daher habe ich auch versucht in den
Demo's möglichst keine Kommentare zu
schreiben da die Sache sonst noch
unübersichtlicher wird. Wer einen
Drucker besitzt ist da klar im Vorteil
und sollte versuchen die Programme
selber zu kommentieren!
Außerdem '(+' steht für eckige Klammer
auf, und ')+' für eckige Klammer zu!!!
Der Editor kennt die eckigen Klammern
wohl aber der Drucker würde sie zu Ä
und Ü verunstalten.


program temp<SM>

var celsius   : real<SM>
    fahrenheit: real<SM>

begin
  writeln(chr(125))<SM>
  writeln('Programm zur Umrechnung
von')<SM>
  writeln('Temperaturen von Grad
Celsius')<SM>
  writeln('in Grad Fahrenheit.')<SM>
  writeln<SM>
  writeln('Geben Sie bitte eine
Temperatur in')<SM>
  write('Celsius an --> ')<SM>
  readln(celsius)<SM>
  writeln<SM>
  fahrenheit:=celsius*(9/5)+32<SM>
  write(celsius:4:2, ' Grad            
        Celsius')<SM>
  writeln ('entsprechen')<SM>
  write(fahrenheit:4:2)<SM>
  writeln(' Grad Fahrenheit.')
end.


Im folgenden werde ich mich weitest-
gehend auf die Beschreibung von
Besonderheiten von Kyan-Pascal be-
schränken.

Bei Kyan-Pascal kann die sogenannte
Programmparameterliste weggelassen
werden. D.h. es müssen im Programmkopf
nicht alle verwendeten Dateinamen
angegeben werden. Z.B.

program test(input, output)

ist nicht notwendig.

writeln(chr(125) entspricht dem ?
chr$(125) Kommando des BASIC, und
löscht damit den Bildschirm.

writeln ('...') entspricht ? "..."<SM>

write ('...') entspricht ? "...."<SM>

Bei der Variablenzuweisung muß ':='
geschrieben werden. Das bedeutet
'definiert als'.

write(fahrenheit:6:2) gibt die Variable
fahrenheit mit 6-2=2 Vorkamma und 2
Nachkommastellen aus. Also z.B. für
fahrenheit=23.5 '__23.5'. Ohne diese
Anweisung würde  2.3E1 ausgegeben
werden. Dies gilt natürlich nur für
real-Zahlen. Bei Integer-Zahlen gibt es
aber eine ähnliche Funktion. a:5 ergibt
für a=23 folgende Ausgabe: '___23'.
('_' steht für Leerzeichen)



Nun aber zu Demo Nummer 2:

Es soll demonstrieren, daß man
Variablenamen so wählen soll daß man an
ihm den Inhalt der Variable erkennt.
Sie dürfen aber nicht zu lang werden.
Kyan-Pascal überprüft nur die ersten 8
Buchstaben. D.h. z.B. fuenfzig und
fuenfziger sind für Pascal ein und die
selbe Variable.

Probieren sie das folgene Programm
WECHSEL einfach einmal aus. Nun
benutzen sie die Funktion 'Ersetzen'
des Editors und ersetzen 'fuffziger'
durch 'fuenfziger'. Sie werden erstaunt
sein welche Folgen diese kleine
Änderung des Programms bewirkt! Den
Compiler stören solche Fehler nicht,
SIE sind dafür verantwortlich das
'Doppelbenennungen' nicht passieren!


program wechsel<SM>

const zwei     = 2<SM>
      fuenf    = 5<SM>
      zehn     = 10<SM>
      fuenfzig = 50<SM>  (* <== *)
      minimum  = 1<SM>
      maximum  = 99<SM>

var betrag,
    fuffziger,        (* <== *)
    zehner,
    fuenfer,
    zweier,
    einser,
    rest      : integer<SM>

begin
  writeln(chr(125))<SM>
  repeat
    writeln('Geben Sie einen Betrag
zwischen')<SM>
    write(minimum, ' und ', maximum, '
ein. --> ')<SM>
    readln(betrag)<SM>
  until (betrag in (+minimum..
maximum)+)<SM>

  fuffziger := betrag div fuenfzig<SM>
  rest      := betrag mod fuenfzig<SM>
  zehner    := rest div zehn<SM>
  rest      := rest mod zehn<SM>
  fuenfer   := rest div fuenf<SM>
  rest      := rest mod fuenf<SM>
  zweier    := rest div zwei<SM>
  einser    := rest mod zwei<SM>

  writeln<SM>
  writeln(betrag:2,  ' Pfennig = ',
          fuffziger, ' Fuenfziger,
')<SM>
  writeln(' ':13, zehner,  ' Zehner,
')<SM>
  writeln(' ':13, fuenfer, ' Fuenfer,
')<SM>
  writeln(' ':13, zweier,  ' Zweier,
')<SM>
  writeln(' ':13, einser,  ' Einser.')
end.


Der Befehl 'write (' ':13)' bewirkt
eine Ausgabe von 13 Spaces. So kann man
z.B. leicht Einrückungen verwirklichen.
5 div 2 ergibt 2. Der div-Befehl
ermittelt den Vorkommateil der Division
7/2 also 3. Analog ergibt 7 mod 2 den
Nachkommateil von 7/2 also 5. Turbo-
Basic-Programmierern dürften diese
Befehle ja bekannt sein. Der Befehl
'betrag in (+minimum..maximum)+'
liefert einen boolean Ausdruck also
'true' oder 'false'. Er überprüft ob
'betrag' innerhalb des mit eckigen!
Klammern gekennzeichneten Bereichs
liegt. Im Beispielprogramm also
zwischen 1 und 99.



Zum 3. Demoprogramm:

Lesen sie sich es bitte erst einmal
durch und versuchen sie es zu
verstehen.
Zur Erklärung ord(ch) entspricht dem
Basic-Befehl asc(ch) und errmittelt den
ATASCII-Code eines Zeichens.


program dualzahl<SM>

var x, ch  : char<SM>
    dezimal: integer<SM>

begin
  writeln(chr(125))<SM>
  dezimal:=0<SM>
  writeln('Programm zur Umrechnung
von')<SM>
  writeln('Dualzahlen in
Dezimalzahlen')<SM>
  writeln<SM>
  writeln('Geben Sie bitte eine
Dualzahl ein')<SM>
  (* Lese Zahl ein *)
  while not(eoln(input)) do
  begin
    read(ch)<SM>
    dezimal:=2*dezimal+ord(ch)-ord('0')
  end<SM>
  writeln<SM>
  writeln('Dies entspricht Dezimal ',
dezimal, '.')
end.


Wahrscheinlich werden sie Probleme mit
der Eingabe haben.
Das Programm gibt seinen Kopf aus und
landet dann bei der while-Schleife.
'eoln(input)' stellt fest ob der
Tastaturpuffer leer ist! Dazu aber
später mehr, für den Moment reicht es
erst einmal aus zu wissen das die
Schleife durchlaufen wird. Nun trifft
das Programm auf read(ch). 'ch' ist ein
char, das heißt ein einzelnes Zeichen.
Der User kann nun beliebig viele
Zeichen auf den Bildschirm schreiben
und seine Eingabe mit 'RETURN' ab-
schließen. In diesem Beispiel möchte
ich '101' annehmen. Diese Zeichen
landen dann aber nicht in 'ch' sondern
im Tastaturpuffer. Der Befehl
'read(ch)' liest nun nur das erste
Zeichen ('1') aus dem Puffer nach 'ch'.
Nun erfolgt in der nächsten Zeile die
eigentliche Umrechnung des Zeichens.
Die while-Schleife ist jetzt beendet.
Das Programm landet also wieder beim
while-Befehl, 'eoln(input)' (end of
line) ergibt den Ausdruck 'false' da ja
noch '01' im Puffer steht. Der Befehl
'read(ch)' liest jetzt "lediglich" das
nächste Zeichen ('0') aus dem Tastatur-
puffer (nicht vom Bildschirm!!!). Jetzt
wird dieses Zeichen erneut umgerechnet,
geprüft ob noch Zeichen im Puffer sind
und ein neues Zeichen ('1') eingelesen
sowie umgerechnet. Nun ist der
Tastaturpuffer leer, 'eoln(input)'
liefert somit 'true', die Schleifenbe-
dingung ist nicht mehr erfüllt und es
wird zur Ausgabe verzweigt.
Zu Beachten ist noch das das Programm
nicht gegen fehlerhafte Eingaben
gesichert ist. Aber das könnt ihr ja
mal versuchen!
Zur Vollständigkeit ist noch zu sagen
das sich nach dem Auslesen der Zeichen
doch noch ein Zeichen im Tastatur-
puffer befindet. Kyan-Pascal speichert
nämlich die 'RETURN'-Taste ebenfalls
ab. Was das bedeutet und wie man dieses
Zeichen wieder aus dem Puffer bekommt
werde ich in der nächste Ausgabe noch
einmal genauer erläutern.

So ich glaube, das reicht für's Erste.
Besonders mit dem 3. Demoprogramm
solltet ihr etwas herum
experimentieren.
Baut doch z.B. mal
'writeln('Hallo')<SM>' hinter dem
Befehl 'read(ch)' ein.

In der nächsten Ausgabe möchte ich mich
ein wenig mit der case-Schleife be-
fassen die es leider in BASIC nicht
gibt. Sowie noch einmal auf den
Tastaturpuffer eingehen.