summaryrefslogtreecommitdiff
path: root/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a')
-rw-r--r--doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a1590
1 files changed, 1590 insertions, 0 deletions
diff --git a/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a
new file mode 100644
index 0000000..1ee80ec
--- /dev/null
+++ b/doc/user-manual/1.7.3-pd/doc/pd.Handbuch.Teil6a
@@ -0,0 +1,1590 @@
+ EUMEL-Benutzerhandbuch
+
+
+ TEIL 6: Erste Hilfe in ELAN
+
+
+Vorwort
+
+Dieser Teil des EUMEL-Handbuchs ist keine "Einführung in die Programmierung
+mit ELAN", sondern ist als Begleitmaterial für einen ELAN-Kurs gedacht.
+Zudem beschreibt das Skript nicht die vollständige Sprache; dafür ist die
+Sprachbeschreibung und das Handbuch vorgesehen. Folgende ELAN-Bücher sind
+z.Zt. erhältlich:
+
+Klingen / Liedtke:
+Programmieren mit ELAN
+Teubner, Stuttgart, 1982
+
+Jähnichen u.a.:
+Systematisches Programmieren mit ELAN
+W. de Gruyter, 1982
+
+Wir haben in dieses Skript auch einige Aufgaben mit aufgenommen, die An-
+fänger auf jeden Fall lösen sollten. Die Aufgaben dienen aber nur dazu, das
+erlernte Wissen über ELAN zu überprüfen und sind keine eigentlichen Program-
+mieraufgaben, die es im begleitenden Kurs geben sollte. Es gibt zwei Arten
+von Aufgaben:
+
+a) HSG (Hätten Sie's gewußt?): Aufgaben, die das bis dahin Gelernte über-
+ prüfen sollen.
+b) TSW (Trau', Schau', wem!): Aufgaben mit Programmen, die Fehler enthalten
+ können. Alle Programme dieses Skripts sind übrigens von der Art TSW.
+
+Es ist auch sinnvoll und notwendig, möglichst viele Programme dieses Skripts
+direkt auf dem Terminal zu probieren und zu verändern. Auf diese Weise wird
+ein Anfänger auch mit den Fehlermeldungen des ELAN-Compilers vertraut.
+
+
+
+Das erste Programm
+
+Gleich am Anfang einer Programmierlaufbahn haben Anfänger eine schwierige
+Hürde zu nehmen: das erste Programm "zum Laufen" zu bringen. Das wird einem
+Anfänger meist nicht leicht gemacht: schließlich hat er mit dem Betriebs-
+system eines Computers zu kämpfen. Ein #ib#Betriebssystem#ie# sorgt u.a. für
+die Steuerung so unterschiedlicher Peripheriegeräte wie Drucker, Lochkarten-
+leser, Magnetplatten und -bänder usw. Zusätzlich hat es dafür Sorge zu
+tragen, daß Informationen sicher gespeichert werden und nicht unbeabsichtigt
+verändert werden können. Letztendlich hat ein Betriebsystem die Aufgabe, die
+Aufträge von Benutzern ("jobs") - und das können mehrere auf einmal sein -
+sicher und effizient bearbeiten zu lassen. Um mit einem Betriebsystem
+"sprechen" zu können, ist meist eine eigene Sprache vorhanden, die Kommando-
+sprache ("job control language", abgekürzt: JCL).
+
+Eine Kommandosprache kann - auf Grund der vielfältigen Aufgaben, die mit
+ihrer Hilfe formuliert werden müssen - mehr oder weniger kompliziert sein.
+Zusätzlich sind Kommandosprachen sehr unterschiedlich: aus leicht einsichti-
+gen Gründen wollen sich Hersteller nicht auf eine Kommandosprache einigen.
+Deshalb können wir die Anweisungen in einer speziellen Kommandosprache hier
+nicht angeben; man erfragt diese am besten. Auf jeden Fall muß etwas getan
+werden, um ein Programm auf einem Rechner "zum Laufen" zu bringen.
+
+Wie bereits erwähnt, beschränken wir uns hier auf die eigentlichen Programme.
+Um den Mechanismus mit den Anweisungen an das Betriebsystem von Anfang
+an kennen zu lernen, denken wir uns ein sehr einfaches Programm aus, das wir
+bearbeiten lassen wollen.
+
+Programm 1:
+
+ put ("Hallo: mein erstes Programm")
+
+Dieses Programm muß nun dem Rechner zur Bearbeitung übergeben werden.
+Auch hier treffen wir auf Unterschiede bei den verschiedenen Rechensystemen:
+bei einigen Rechnern muß ein solches Programm (mit Anweisungen der
+Kommandosprache) auf Lochkarten übertragen werden, bei anderen dagegen
+tippt man das Programm direkt an einem Sichtgerät ("Terminal") ein. Die
+Ausgabe erfolgt dann über einen Schnelldrucker oder auch über das Sichtgerät.
+Um von Geräten bestimmter Installationen zu abstrahieren, nennen wir im
+folgenden das Eingabemedium #ib#Eingabegerät#ie# und das Gerät, auf dem die
+Resultate erscheinen, dementsprechend Ausgabegerät.
+
+Aufgabe (TSW):
+
+ Versuchen Sie, Programm 1 auf dem Rechner Ihrer Installation zu "rechnen".
+Übungsziel: Umgang mit dem Betriebsystem
+
+
+Das Ergebnis unseres ersten Programms ist nun das Erscheinen des Textes:
+'Hallo: mein erstes Programm'. Was ist hier passiert? Da ein Rechner ein
+ELAN-Programm meist nicht direkt ausführen kann, muß es in eine Form
+gebracht werden, die der Rechner "versteht". Diese Form ist wiederum eine
+(sehr andersartige und - für Menschen - nicht leicht verständliche) Sprache,
+die Maschinensprache. Man muß also ein ELAN-Programm übersetzen. Dies wird
+von einem Programm (und nicht etwa einer festverdrahteten Schaltung) vorge-
+nommen, einem Übersetzer. Eine bestimmte Art von Übersetzer heißt Compiler;
+er übersetzt ein Programm als Ganzes (im Gegensatz zu einem Interpreter, der
+nur einzelne Anweisungen übersetzt und anschließend ausführt). Darum sind
+bei ELAN-Programmen, die meist durch Compiler übersetzt ("kompiliert")
+werden, zwei Phasen zu unterscheiden:
+
+a) Übersetzungsphase:
+
+ In dieser Phase wird ein ELAN-Programm (man spricht von Quellprogramm
+ bzw. "source program") in ein äquivalentes Maschinenprogramm (Objektpro-
+ gramm) transformiert. Dabei überprüft der Übersetzer das Quellprogramm
+ auf eventuelle Fehler (Anweisungen, die nicht der ELAN-Sprachbeschreibung
+ entsprechen). Bei solchen Fehlern, die ein Compiler entdecken kann,
+ spricht man von syntaktischen Fehlern oder von Fehlern zur Übersetzungs-
+ zeit.
+
+b) Bearbeitungsphase:
+
+ In dieser Phase ("run time") wird das übersetzte (Maschinen-) Programm
+ abgearbeitet. Auch hier können Fehler auftreten (z.B. wenn auf einen Wert
+ vom Programm zugegriffen wird, der noch gar nicht berechnet wurde).
+ Solche Fehler nennt man Laufzeitfehler.
+
+Haben wir das erste Programm so geschrieben, wie oben angegeben, dürften
+keine Fehler entdeckt werden und das Programm wird (hoffentlich korrekt, d.h.
+mit den geforderten Ergebnissen) beendet. Was für ein Programm haben wir nun
+geschrieben bzw. was haben wir vom Rechner verlangt?
+
+Das Wort 'put' bezeichnet eine Prozedur. Eine Prozedur ist ein Algorithmus
+(hier mit Parametern): eine bestimmte Sammlung von Anweisungen und unter
+Umständen Daten. Eine solche Prozedur können wir in einem Programm unter
+einem Namen (nämlich 'put') ansprechen und ausführen lassen. Man spricht
+dann von dem Aufruf einer Prozedur, wenn ein Prozedurname geschrieben wird.
+Von einer Prozedur brauchen wir nur zu wissen, was die Prozedur macht, aber
+gottseidank nicht, wie sie es macht.
+
+Eine Prozedur wie 'put' ist vorgefertigt und einfach benutzbar, wobei wir
+später sehen werden, wie man solche Prozeduren selber schreiben kann. Die
+Prozedur 'put' hat einen Parameter, nämlich den in Klammern geschriebenen
+Text, der auf dem Ausgabegerät ausgegeben werden soll. Wir können eine
+solche Prozedur auch mit anderen Parametern versehen und mehrmals aufrufen:
+
+Programm 2:
+
+ put ("Programm:");
+ put (2)
+
+Mit dem zweiten Programm ist es uns gelungen, ein Programm mit zwei Anwei-
+sungen zu schreiben (dabei ist der Parameter bei dem ersten Aufruf der
+'put'-Prozedur ein Text, beim zweiten Parameter eine ganze Zahl).
+
+ELAN ist eine formatfreie Sprache, d.h. Anweisungen können so auf eine Zeile
+verteilt werden, wie es uns gefällt und zweckmäßig erscheint.
+
+Programm 3:
+
+ put ("mein"); put (3); put (".Programm")
+
+Man kann also eine oder mehrere Anweisungen auf eine Zeile schreiben oder
+eine Anweisung über mehrere Zeilen. Das setzt jedoch voraus, daß die Anwei-
+sungen voneinander getrennt werden (schließlich muß der Übersetzer erkennen
+können, wo eine Anweisung anfängt und aufhört). Das ist besonders notwendig,
+weil man in Namen in ELAN beliebig Leerzeichen zur besseren Lesbarkeit
+verwenden kann.
+
+
+Programm 4:
+
+ p u t ( "aha");
+ put ("aha")
+
+Beide Anweisungen bewirken also das Gleiche.
+
+Die Trennung von Anweisungen erfolgt in ELAN durch das Trennsymbol
+Semikolon. Es bedeutet soviel wie: "führe die nächste Anweisung aus". Aus
+diesem Grund darf hinter der letzten Anweisung eines Programms kein Semiko-
+lon geschrieben werden (es folgt ja auch keine Anweisung mehr).
+
+Der Aufruf einer Prozedur (wie z.B. 'put') verlangt von unserem Rechner im-
+mer eine Leistung. Wollen wir aber in einem Programm eine Bemerkung schrei-
+ben (z.B. um uns etwas zu merken), dann können wir einen Kommentar schrei-
+ben, der vom Übersetzer überlesen und somit keinen Einfluß auf die Aus-
+führung eines Programms hat. Ein Kommentar in ELAN wird durch die Zeichen
+(* und *) eingeschlossen und darf über mehrere Zeilen gehen. Kommentare sind
+in ELAN aber nur in wenigen Fällen notwendig, weil wir Programme durch
+andere Mittel gut lesbar machen können.
+
+
+
+Ziel der Programmierung
+
+Was wollen wir eigentlich mit dem Programmieren von Computern erreichen?
+Häufig wiederkehrende und somit oft langweilige Tätigkeiten oder solche, die
+besonders schnell erledigt werden müssen, sollen von dem "Werkzeug Computer
+erledigt werden. Gehaltsberechnungen, Unterstützung beim Schreiben von
+Texten, Katalogsysteme für Bibliotheken, Steuerung von Walzstraßen usw. sind
+typische Aufgaben für Computer.
+
+Bei der Programmierung wird also versucht, Objekte (wie z.B. Geld bei einer
+Gehaltsberechnung) und Prozesse (wie z.B. die Simulation von Wirtschaftsab-
+läufen) der realen Welt mit Hilfe von Programmen in einem Computer nachzu-
+bilden und nach bestimmten Vorstellungen so zu verändern, daß man "brauch-
+bare" Ergebnisse erlangt. In einem Programm sind Befehle an einen Rechner
+für eine solche Abbildung enthalten. Die Befehle in einem Programm werden
+Anweisungen genannt. Ein Programmierer muß also folgendes tun:
+
+1. Abbilden von Objekten und Prozessen der realen Welt in ein Programm.
+ Dabei müssen die Bedingungen der Aufgabe beachtet werden. Was das Pro-
+ gramm Programm leisten soll, wird darum in einer Spezifikation festgelegt.
+
+2. Einbringen des Programms in einen Rechner und Bearbeitung desselben. Die
+ Formulierung von Anweisungen in einem Programm erfolgt in einer bestimmten
+ Sprache, nämlich einer Programmiersprache.
+
+3. Interpretation der Ergebnisse.
+
+
+
+Das Konzept des Datentyps
+
+Befassen wir uns vorerst nur mit Objekten. Sicherlich gibt es sehr viele Ob-
+jekte in unserer Welt. Einige von ihnen haben aber gleiche Eigenschaften:
+
+- Fahrzeuge (Autos, Mofas, Dreiräder) bringen uns von Ort A nach Ort B.
+
+- Geld (Münzen, Geldscheine, Murmeln, Franc, DM) erlaubt es, etwas zu kaufen.
+
+- Schreibgeräte (Bleistift, Kugelschreiber, Schreibmaschine) sind die Werk-
+ zeuge von Leuten, die etwas zu schreiben haben.
+
+- ...
+
+Es ist also möglich, einige Objekte der realen Welt in Klassen zusammenzu-
+fassen. Eine solche Zusammenfassung kann hinsichtlich gleicher Eigenschaften
+bzw. gleicher Operationen, die für solche Objekte zugelassen sind, erfolgen.
+Eine Klasse von Objekten mit gleichen Eigenschaften wird in Programmier-
+sprachen Datentyp genannt. Dabei hat ein Datentyp immer einen Namen, der die
+Klasse von Objekten sinnvoll kennzeichnet. Als ein Datenobjekt wird ein
+Exemplar eines Datentyps (also ein spez. Objekt einer Klasse) bezeichnet.
+
+Datentypen sind in ELAN ein zentrales Konzept. Jedes der in einem ELAN-
+Programm verwandten Datenobjekte hat einen Datentyp; somit kann man Daten-
+typen auch als Eigenschaften von Datenobjekten ansehen. Für jeden Datentyp
+sind nur spezielle Operationen sinnvoll. Z.B. sind für einen Datentyp
+"UBoot" die Operationen "erstellen", "tauchen", "auftauchen", "versenken"
+und "lieber nicht verwenden" sinnvoll, aber nicht die Operation "+" wie bei
+ganzen Zahlen. Man kann nun Übersetzern die Aufgabe überlassen zu überprüfen,
+ob stets die richtige Operation auf einen Datentyp angewandt wird.
+
+Aufgabe (HSG):
+
+ Was ist ein Datentyp? Welche Funktion erfüllen Datentypen?
+Übungsziel: Datentyp-Konzept
+
+Einige Datentypen spielen bei der Programmierung eine besondere Rolle, weil
+sie häufig benötigt werden. In ELAN sind das die Datentypen für
+
+- ganze Zahlen. Dieser Datentyp wird INT (für "integer") genannt.
+
+- reelle Zahlen (REAL).
+
+- Zeichen und Zeichenfolgen (TEXT).
+
+- Wahrheitswerte (BOOL).
+
+Diese Typen werden in ELAN elementare Datentypen genannt. Für effiziente
+Rechnungen mit elementaren Datentypen gibt es in den meisten Rechnern
+spezielle Schaltungen, so daß die Hervorhebung und besondere Rolle, die
+sie in Programmiersprachen spielen, gerechtfertigt ist. Zudem hat man
+Werte-Darstellungen innerhalb von Programmen für die elementaren Datentypen
+vorgesehen, was wir im nächsten Abschnitt erklären wollen.
+
+Im weiteren Teil dieses Skripts werden wir uns zunächst auf die Behandlung
+der elementaren Datentypen beschränken. Das bedeutet für den Programmierer,
+daß er alle Objekte der realen Welt mit Hilfe der elementaren Datentypen in
+den Computer abbilden muß. Das kann manchmal sehr schwierig sein (wie bilden
+wir z.B. Personen oder UBoote mit den elementaren Datentypen ab?). Später
+werden wir dann Möglichkeiten kennenlernen, neue - problemgerechte -
+Datentypen in ELAN zu formulieren.
+
+
+
+Denoter (Werte-Repräsentationen) elementarer Datentypen
+
+Wenn wir mit Objekten elementarer Datentypen arbeiten, müssen wir die
+Möglichkeit haben, Werte in ein Programm zu schreiben. Leider kann man einen
+Wert "an sich" in einem Programm nicht direkt angeben. Schreiben wir z.B.
+4711, dann meinen wir zwar einen INT-Wert, haben aber die Ziffern 4, 7, 1 und
+1 geschrieben. Der eigentliche Wert wird in unserem Kopf oder - für unsere
+Zwecke - in einem Rechner gebildet.
+
+Die Werte-Darstellungen oder Werte-Repräsentationen, die in ELAN "Denoter"
+genannt werden, sind für jeden Datentyp unterschiedlich. Wie bereits erwähnt,
+haben alle Datenobjekte in ELAN (also auch Denoter) nur einen - vom Über­
+setzer feststellbaren - Datentyp. Aus der Form eines Denoters ist also der
+Datentyp erkennbar:
+
+- INT-Denoter:
+ Bestehen aus einer Aneinanderreihung von Ziffern. Beispiele:
+
+ 17, 007, 32767, 0
+
+ Führende Nullen spielen bei der Bildung des Wertes keine Rolle (sie werden
+ vom ELAN-Compiler überlesen). Negative INT-Denoter gibt es nicht (wie
+ negative Werte-Darstellungen in einem Programm geschrieben werden, lernen
+ wir bei den Ausdrücken).
+
+- REAL-Denoter:
+ Hier gibt es zwei Formen. Die erste besteht aus zwei INT-Denotern, die
+ durch einen Dezimalpunkt getrennt werden. Beispiele:
+
+ 0.314159, 17.28
+
+ Der Dezimalpunkt wird analog der deutschen Schreibweise als Komma
+ verwendet. Negative REAL-Denoter gibt es wiederum nicht.
+
+ Eine zweite Form wird kurioserweise als "wissenschaftliche Notation" be-
+ zeichnet. Sie findet dann Verwendung, wenn sehr große oder Zahlen, die
+ nahe bei Null liegen, dargestellt werden müssen. Beispiele:
+
+ 3.0 e5, 3.0e-5
+
+ Der (INT-) Denoter hinter dem Buchstaben e gibt an, wie viele Stellen der
+ Dezimalpunkt nach rechts (positive Werte) oder nach links zu verschieben
+ ist. Dieser Wert wird Exponent, der Teil vor dem Buchstaben e Mantisse
+ genannt.
+
+- TEXT-Denoter:
+ TEXT-Denoter werden in Anführungszeichen eingeschlossen. Beispiele:
+
+ "Das ist ein TEXT-Denoter"
+ "Jetzt ein Text-Denoter ohne ein Zeichen: ein leerer Text"
+ ""
+
+ Beachte, daß das Leerzeichen ebenfalls ein Zeichen ist. Soll ein An-
+ führungszeichen in einem TEXT erscheinen (also gerade das Zeichen, welches
+ einen TEXT-Denoter beendet), so muß es doppelt geschrieben werden:
+
+ "Ein TEXT mit dem ""-Zeichen"
+ "Ein TEXT-Denoter nur mit dem ""-Zeichen:"
+ """"
+
+ Manchmal sollen Zeichen in einem TEXT-Denoter enthalten sein, die auf dem
+ Eingabegerät nicht zur Verfügung stehen. In diesem Fall kann der Code-
+ Wert des Zeichens angegeben werden:
+
+ ""32""
+
+ bedeutet z.B. das (ASCII-) Leerzeichen. Der Code-Wert eines Zeichens er-
+ gibt sich aus einer Code-Tabelle (installationsspezifisch), in der jedem
+ Zeichen eine ganze Zahl zugeordnet ist.
+
+- BOOL-Denoter:
+ Es gibt nur zwei BOOL-Denoter: TRUE (für "wahr") und FALSE (für "falsch").
+
+Nun wird auch klar, was für Parameter wir in den obigen Programmen verwandt
+haben. Es waren natürlich TEXT- bzw. INT-Denoter.
+
+
+Aufgabe (TSW):
+
+ Welche der folgenden Denotationen ist falsch?
+
+ a) 1. e) 1 . 0 i) 007
+ b) -1 f) "" j) "Ein "Getuem" stellt sich vor"
+ c) """ g) """"
+ d) "das ist ein text" h) TRUE k) 1.0 e 37
+
+Übungsziel: Lernen von Denotationen
+
+
+
+ELAN-Datenobjekte
+
+Wie bereits erwähnt, wollen wir mit Hilfe von Programmen Datenobjekte so
+verändern, daß wir erwünschte Ergebnisse erhalten. Meist wird zu dieser Ver-
+änderung von Datenobjekten "Rechnen" gesagt, obwohl - wie wir gleich sehen
+werden - nicht nur numerische Objekte manipuliert werden. Die Veränderung
+der Datenobjekte findet zur "Laufzeit" (nicht zur Übersetzungszeit) im
+Rechner statt. Die Darstellung eines Werts in einem Rechner zur Laufzeit
+eines Programms wird #ib#Repräsentation#ie# genannt. Wenn es eindeutig ist,
+daß es sich nur um die Repräsentation im Rechner handelt, sprechen wir kurz
+von Werten.
+Da also ein Datenobjekt wechselnde Werte annehmen kann, brauchen wir eine
+Möglichkeit, es in einem Programm anzusprechen, egal welchen Wert das Objekt
+zu einem Zeitpunkt beinhaltet. Zu diesem Zweck können wir einem Datenobjekt
+einen Namen geben (wie z.B. einen Personennamen, hinter dem sich eine wirk­
+liche Person "verbirgt"). Wenn wir also den Namen des Datenobjekts in ein
+Programm schreiben, dann meinen wir (meist) den Wert des Datenobjekts, den
+es zu diesem Zeitpunkt besitzt.
+
+Nun sollen die zu behandelnden Datenobjekte ja auch neue Werte erhalten. In
+diesem Fall müssen wir die Speicherstelle finden, in die der neue Wert ge-
+bracht werden soll. Für diesen Zweck benutzen wir ebenfalls den Namen, zu-
+sätzlich zu der Angabe einer Operation, durch die das Objekt einen neuen
+Wert erhalten soll. Diese Operation (Wert "schreiben") nennen wir Zuweisung.
+Der Zuweisungs-Befehl wird ':=' geschrieben. Beispiel:
+
+ a := 5
+
+Bedeutet, daß das Datenobjekt mit dem Namen 'a' den Wert '5' erhält.
+
+Von manchen Datenobjekten wissen wir, daß wir ihnen nur einmal einen Wert
+geben wollen. Sie sollen also nicht verändert werden. Oder wir wissen, daß
+in einem Programmbereich ein Datenobjekt nicht verändert werden soll. Um ein
+unbeabsichtigtes Verändern zu verhindern, wird in ELAN dem Namen eines
+Datenobjekts ein zusätzlicher Schutz mitgegeben: das Zugriffsrecht oder
+Accessrecht. Es besteht aus der Angabe der Worte VAR (für Lesen und Ver-
+ändern) oder CONST (für ausschließliches Lesen).
+
+
+
+Die Deklaration (Vereinbarung) von Datenobjekten
+
+Wollen wir ein Datenobjekt in einem Programm verwenden, so müssen wir dem
+Übersetzer mitteilen, welchen Datentyp und welches Accessrecht das Objekt
+haben soll. Das dient u.a. dazu, nicht vereinbarte Namen (z.B. verschriebene)
+vom Übersetzer entdecken zu lassen. Weiterhin ist aus dem bei der Deklaration
+angegebenen Datentyp zu entnehmen, wieviel Speicherplatz für das Objekt zur
+Laufzeit zu reservieren ist. Beispiel:
+
+INT VAR mein datenobjekt
+
+Zuerst wird der Datentyp, dann das Accessrecht und schließlich der Name des
+Datenobjekts angegeben. Wie werden nun Namen in ELAN formuliert?
+
+Das erste Zeichen eines Namens muß immer ein kleiner Buchstabe sein. Danach
+dürfen beliebig viele kleine Buchstaben, aber auch Ziffern folgen. Zur bes-
+seren Lesbarkeit können (wie bei den obigen Prozedurnamen) Leerzeichen in
+einem Namen erscheinen, die aber nicht zum Namen zählen. Beispiele:
+
+ name1
+ n a m e 1
+ x27
+ gehalts konto
+ das ist ein langer name
+
+Verschiedene Datenobjekte mit gleichem Datentyp und Accessrecht dürfen in
+einer Deklaration angegeben werden (durch Kommata trennen). Mehrere Dekla-
+rationen werden - genauso wie Anweisungen - durch das Trennsymbol
+voneinander getrennt. Beispiele:
+
+ INT VAR mein wert, dein wert, unser wert;
+ BOOL VAR listen ende;
+ TEXT VAR zeile, wort
+
+
+
+Die Initialisierung von Datenobjekten
+
+Um mit den so vereinbarten Datenobjekten arbeiten zu können, muß man ihnen
+eine Wert geben. Hat ein Datenobjekt noch keinen Wert erhalten, so sagt man,
+sein Wert sei undefiniert. Das versehentliche Arbeiten mit undefinierten
+Werten ist eine beliebte Fehlerquelle. Deshalb wird von Programmierern
+streng darauf geachtet, diese Fehlerquelle zu vermeiden. Eine Wertgebung an
+ein Datenobjekt kann (muß aber nicht) bereits bei der Deklaration erfolgen,
+was man in ELAN Initialisierung nennt. Beispiele:
+
+ INT CONST gewuenschtes gehalt :: 12 000;
+ TEXT VAR zeile :: "";
+ REAL CONST pi :: 3.14159;
+ BOOL VAR bereits sortiert :: TRUE
+
+Allerdings: für mit CONST vereinbarte Datenobjekte ist die Initialisierung
+die einzige Möglichkeit, ihnen einen Wert zu geben.
+
+Die Initialisierung erfolgt mit Hilfe des '::'-Symbols. Anschließend folgt
+der Wert, den das Datenobjekt erhalten soll. (In den Beispielen haben wir
+nur Denoter geschrieben. Es sind aber auch allgemeinere Ausdrücke erlaubt.).
+Es ist nun möglich, mit der oben erwähnten 'put'-Prozedur auch den Wert von
+Datenobjekten ausgeben zu lassen.
+
+
+Programm 5:
+
+ INT VAR nummer :: 5;
+ TEXT CONST bemerkung :: ".Programm";
+ put (nummer);
+ put (bemerkung)
+
+Beachte dabei, daß bei der Aufführung eines Namens in diesem Fall immer der
+Wert des Datenobjekts gemeint ist. Auch die 'put'-Prozedur druckt nicht etwa
+den Namen des Datenobjekts oder die Adresse der Speicherstelle, sondern
+ebenfalls den Wert.
+
+
+Aufgabe (HSG):
+
+ Welche Aufgabe erfüllen Deklarationen? Was heißt: "Eine Variable hat
+ einen undefinierten Wert"? Was ist eine Initialisierung? Was ist ein
+ CONST-Datenobjekt? Warum müssen CONST-Datenobjekte initialisiert
+ werden?
+Übungsziel: Verständnis von Deklarationen und Accessrecht
+
+
+
+Schlüsselworte
+
+Einige Worte haben in ELAN eine feste Bedeutung und können somit nicht -
+wie etwa Namen - frei gewählt werden. Solche Worte werden bei den meisten
+ELAN-Übersetzern mit großen Buchstaben geschrieben, wie z.B. VAR, CONST,
+INT oder REAL u.a.m. Wie wir später sehen werden, besteht die Möglichkeit,
+neue Schlüsselworte einzuführen. Halten wir vorläufig fest, daß feste
+Bestandteile der Sprache (wie z.B. CONST oder VAR) und Datentypen (wie INT
+oder REAL) Schlüsselworte sind, also mit großen Buchstaben geschrieben
+werden.
+
+
+
+Ausdrücke
+
+Nun wäre es natürlich schlecht, wenn Programmierer nicht mehr machen könnten,
+als Werte ausgeben. Als erste Stufe von etwas komplexeren "Rechnungen"
+dürfen Ausdrücke gebildet werden. Ausdrücke sind eine Zusammenstellung von
+Datenobjekten (Denoter, VAR- oder CONST-Objekte) und Operatoren. Schauen wir
+uns dazu erst ein Programm an:
+
+
+Programm 6:
+
+ INT CONST wert 1 :: 1,
+ wert 2 :: 2,
+ wert 3 :: 3;
+
+ put (wert1 + wert2);
+ put (wert2 - wert1);
+ put (wert2 * wert3);
+ put (wert3 DIV wert2);
+ put (wert2 ** wert3)
+
+In diesem Programm werden drei Datenobjekte initialisiert. Anschließend
+werden jeweils die Werte von zwei Objekten addiert (Operatorzeichen: '+'),
+subtrahiert ('-'), multipliziert ('*'), dividiert (ganzzahlige Division ohne
+Rest: 'DIV') und potenziert ('**'). Dies sind Operatoren, die zwei Operanden
+haben: man nennt sie dyadische Operatoren. Die monadischen Operatoren da-
+gegen haben nur einen Operanden. Beispiel:
+
+ put ( - wert1)
+
+Operatoren in ELAN werden - wie wir an den obigen Beispielen sehen - durch
+ein oder zwei spezielle Zeichen oder durch große Buchstaben (in den Fällen,
+in denen kein "vernünftiges" Zeichen mehr zur Verfügung steht) als Schlüssel-
+wort dargestellt.
+
+Als Operanden (also die Datenobjekte, auf die ein Operator "wirken" soll)
+eines Operators darf ein VAR- oder CONST-Datenobjekt, aber auch ein Denoter
+verwendet werden. Das Resultat eines Operators (also das Ergebnis einer
+Berechnung) ist bei den obigen Ausdrücken wieder vom Datentyp INT mit dem
+Accessrecht CONST. Darum ist es erlaubt, solch einen Ausdruck wiederum als
+Operanden zu verwenden. Praktisch bedeutet dies, daß wir mehrere Operatoren
+und Datenobjekte zusammen in einem Ausdruck haben dürfen.
+
+
+Programm 7:
+
+ INT CONST wert 1 :: 1,
+ wert 2 :: 2,
+ wert 3 :: 3;
+
+ put (wert2 + 3 - wert2 * wert3);
+ put (- wert2 * wert3)
+
+Nun haben wir eine Schwierigkeit: Der Ausdruck in der ersten 'put'-Anweisung
+ist mehrdeutig, d.h. kann - je nach Reihenfolge der Auswertung - unter-
+schiedliche Ergebnisse als Resultat liefern. Beispiel:
+
+ a) (wert2 + 3 = 5) - (wert2 * wert3 = 6) = -1
+ b) ((wert2 + 3 = 5) - wert2 = 3) * 3 = 9
+
+Es kommt also auf die Reihenfolge der Auswertung von Operatoren an. Diese
+kann man durch die Angabe von Klammern steuern. Beispiel:
+
+ (a + b) * (a + b)
+
+Es wird jeweils erst 'a + b' ausgewertet und dann erst die Multiplikation
+durchgeführt. In ELAN ist es erlaubt, beliebig viel Klammernpaare zu ver-
+wenden (Regel: die innerste Klammer wird zuerst ausgeführt). Es ist sogar
+zulässig, Klammern zu verwenden, wo keine notwendig sind, denn überflüssige
+Klammernpaare werden überlesen. Beispiel:
+
+ ((a - b)) * 3 * ((c + d) * (c - d))
+
+Somit können wir beliebig komplizierte Ausdrücke formulieren. (Was man aber
+vermeiden sollte, weil sie leicht zu Fehlern führen. Stattdessen kann man
+einen komplizierten Ausdrücke in mehrere (einfachere) zerlegen.)
+
+Um solche Ausdrücke einfacher zu behandeln und sie so ähnlich schreiben zu
+können, wie man es in der Mathematik gewohnt ist, wird in Programmiersprachen
+die Reihenfolge der Auswertung von Operatoren festgelegt. In ELAN wurden
+neun Ebenen, Prioritäten genannt, festgelegt:
+
+
+Priorität Operatoren
+
+ 9 alle monadischen Operatoren
+ 8 **
+ 7 *, /, DIV, MOD
+ 6 +, -
+ 5 =, <>, <, <=, >, >=
+ 4 AND
+ 3 OR
+ 2 alle übrigen, nicht in dieser Tabelle aufgeführten
+ dyadischen Operatoren
+ 1 :=
+
+
+(Die bis jetzt noch nicht erwähnten Operatoren in der Tabelle werden wir in
+den weiteren Abschnitten besprechen.)
+
+Operatoren mit der höchsten Priorität werden zuerst ausgeführt, dann die mit
+der nächst höheren Priorität usw. Operatoren mit gleicher Priorität werden
+von links nach rechts ausgeführt. Dadurch ergibt sich die gewohnte Abarbei-
+tungsfolge wie beim Rechnen. Beispiel:
+
+ -2 + 3 * 2 ** 3
+
+ a) -2
+ b) 2 ** 3
+ c) 3 * (2 ** 3)
+ d) ((-2)) + (3 * (2 ** 3))
+
+Wie bereits erwähnt, ist es immer erlaubt, Klammern zu setzen. Ist man sich
+also über die genaue Abarbeitungsfolge nicht im Klaren, so kann man Klammern
+verwenden.
+
+
+Aufgabe (HSG):
+
+ Welche INT-Werte ergeben sich?
+
+ a) 14 DIV 4 e) -14 DIV -4
+ b) + 14 DIV 4 f) 2 * 3 DIV 2 ** 2 * 4
+ c) -14 DIV 4 g) 2 ** 3 ** 4
+ d) 14 DIV -4 h) 3 + 4 * 2 + 3
+
+Übungsziel: Arithmetische Ausdrücke
+
+
+Aufgabe (HSG):
+
+ Bilden Sie für folgende mathematische Formeln entsprechende ELAN-
+ Ausdrücke:
+
+ a b a+b
+ a) - c d) a g) - ---
+ b c
+
+
+ a+b b a c
+ b) --- e) -a h) - * -
+ c+d b d
+
+
+ a+b -b c
+ c) --- e f) a i) (a*b)
+ c+d
+
+Übungsziel: Arithmetische Ausdrücke formulieren
+
+
+
+Generische Operatoren und Prozeduren
+
+Bis jetzt wurden nur Ausdrücke mit INT-Operanden verwendet. Wie sieht es
+jetzt mit REALs aus?
+
+
+Programm 8:
+
+ put (1.0 + 2.0);
+ put (2.0 - 1.0);
+ put (2.0 * 3.0);
+ put (3.0 / 2.0);
+ put (2.0 ** 3.0)
+
+Man beachte die Unterschiede zum Programm 7: Wir müssen nun REAL-Denoter
+verwenden (mit INT-Denotern zu arbeiten wäre ein Fehler). Der Divisions-
+Operator hat sich nun von 'DIV' zu '/' gewandelt. Die Ergebnisse sind nun
+nicht INT-, sondern REAL-Werte. Für die Reihenfolge der Auswertung der
+Operatoren sowie die Verwendung von Klammern gilt das für INT-Ausdrücke
+gesagte.
+
+Wir haben den '+'-Operator in zwei verschiedenen Formen gesehen: in Programm
+7 mit Operanden vom Datentyp INT, ein INT-Resultat liefernd, und in Programm
+8 das gleiche mit REALs. Es liegen also zwei verschiedene Operatoren vor,
+die aber den gleichen Namen (Zeichen: '+') haben.
+
+In ELAN ist es somit möglich, unterschiedlichen Operatoren (aber auch Proze-
+duren) gleiche Namen zu geben. Solche Operatoren werden generische Opera-
+toren genannt. Ein ELAN-Compiler wählt den richtigen Operator aufgrund der
+Datentypen der Operanden aus. Oft werden die verfügbaren Operatoren wie folgt
+dokumentiert:
+
+ INT OP + (INT CONST links, rechts)
+
+Diese Form nennt man einen "Operator-Kopf". Sie wird in ELAN-Programmen bei
+der Definition von Operatoren benötigt. Dabei steht OP für "OPERATOR". Die
+Angabe des Datentyps davor gibt den Datentyp des Resultats des Operators an.
+Zwischen 'OP' und der öffnenden Klammer steht der Name des Operators (hier:
+'+'). In den Klammern werden die Datentypen und das Accessrecht der
+Operanden angegeben. CONST bedeutet hier: der Operand darf vom Operator
+nicht verändert werden, während bei VAR (was normalerweise ja nicht sein
+sollte!) ein Operand bei der Abarbeitung eines Operators verändert werden
+kann.
+
+Damit wir solche Definitionen besser beherrschen, geben wir noch weitere
+Beispiele an:
+
+ INT OP - (INT CONST operand)
+ REAL OP / (INT CONST l, r)
+
+Bei dem ersten Operator handelt es sich um den monadischen Operator '-' für
+INT-Operanden (z.B.: 'INT VAR a :: 1; put (-a)'), während es sich bei dem
+zweiten Operator um eine Divisions-Operator handelt, der jedoch ein REAL-
+Resultat liefert (z.B.: 'put (3 / 2)' liefert 1.5). Der MOD-Operator liefert
+den Rest einer Division:
+
+ INT OP MOD (INT CONST l, r)
+ REAL OP MOD (REAL CONST l, r)
+
+Die Beschreibung von generischen Prozeduren verläuft analog. Beispiele:
+
+ PROC put (INT CONST wert)
+ PROC put (REAL CONST wert)
+
+Hier wird das Wort 'OP' durch 'PROC' (für 'PROCEDURE') ersetzt. Die Angaben
+in Klammern bezeichnen nun nicht Operanden, sondern Parameter.
+
+Über die verfügbaren Operatoren und Prozeduren für INT- und REAL-Datenob-
+jekte kann man sich im ELAN-Handbuch oder im EUMEL-Benutzerhandbuch infor-
+mieren. Einige - aber nicht alle - der Operatoren und Prozeduren (auch für
+andere Datentypen) werden wir erklären, wenn wir sie in Programmen benötigen.
+
+
+
+Die Zuweisung
+
+Ein spezieller Operator ist die Zuweisung (Zeichen: ':='). Dieser Operator
+hat immer die geringste Priorität, wird also immer als letzter eines Aus-
+drucks ausgeführt. Die Zuweisung wird verwendet, um einer Variablen einen
+neuen Wert zu geben. Beispiel:
+
+ a := b
+
+Hier wird der Wert von 'b' der Variablen 'a' zugewiesen. Der vorher vor-
+handene Wert von 'a' geht dabei verloren. Man sagt auch, der Wert wird über-
+schrieben. Auf der rechten Seite (also als rechter Operand) des ':='
+Operators darf auch ein Ausdruck stehen. Beispiel:
+
+ a := b + c
+
+Hier wird das Resultat von 'b + c' an die Variable 'a' zugewiesen. Man be-
+achte dabei die Prioritäten der Operatoren '+' (Priorität 6) und ':=' (Pri-
+orität 1): die Addition wird vor der Zuweisung ausgeführt. Die Auswertung
+von Zuweisungen mit Ausdrücken muß immer so verlaufen, da die Zuweisung
+stets die niedrigste Priorität aller Operatoren hat.
+
+Schauen wir uns zum besseren Verständnis die Definitionen des (natürlich
+auch generischen) Operators ':=' an:
+
+ OP := (INT VAR ziel, INT CONST quelle)
+ OP := (REAL VAR ziel, REAL CONST quelle)
+ OP := (TEXT VAR ziel, TEXT CONST quelle)
+ OP := (BOOL VAR ziel, BOOL CONST quelle)
+
+Der Operator ':=' liefert also kein Resultat (man sagt auch, er liefert
+keinen Wert) und verlangt als linken Operanden ein VAR-Datenobjekt (an den
+der Wert der rechten Seite zugewiesen werden soll). Der Wert des linken
+Operanden wird also verändert. Für den rechten Operanden ist durch CONST
+sichergestellt, daß er nur gelesen wird.
+
+Oft kommt es vor, daß ein Objekt auf der linken und rechten Seite des Zuwei-
+sungsoperators erscheint, z.B. wenn ein Wert erhöht werden soll. Beispiele:
+
+ a := a + 1;
+ a := a + 17
+
+Hier wird der "alte", aktuelle Wert von 'a' genommen, um '1' erhöht und dem
+Objekt 'a' zugewiesen. Man beachte, daß hier in einer Anweisung ein Datenob-
+jekt unterschiedliche Werte zu unterschiedlichen Zeitpunkten haben kann.
+
+In solchen Fällen darf man den Operator INCR verwenden:
+
+ a INCR 1;
+ a INCR 17
+
+Analoges gilt für den Operator DECR, bei dem ein Wert von einer Variable
+subtrahiert wird. Also:
+
+ OP INCR (INT VAR ziel, INT CONST dazu)
+ OP INCR (REAL VAR ziel, REAL CONST dazu)
+
+ OP DECR (INT VAR ziel, INT CONST abzug)
+ OP DECR (REAL VAR ziel, REAL CONST abzug)
+
+Schauen wir uns folgendes Programm an, bei dem zwei Werte vertauscht werden:
+
+
+Programm 9:
+
+ INT VAR a, b, x;
+
+ get (a);
+ get (b);
+ x := a;
+ a := b;
+ b := x;
+ put (a);
+ put (b)
+
+Wie wir an diesem Beispiel sehen, existieren nicht nur 'put'-Prozeduren,
+sondern auch 'get'-Prozeduren, die einen Wert vom Eingabemedium einlesen.
+Es gibt folgende 'get'- Prozeduren (die 'put'-Prozeduren führen wir der
+Vollständigkeit halber auch mit auf):
+
+ PROC get (INT VAR wert)
+ PROC get (REAL VAR wert)
+ PROC get (TEXT VAR wert)
+
+ PROC put (INT CONST wert)
+ PROC put (REAL CONST wert)
+ PROC put (TEXT CONST wert)
+
+
+Aufgabe (HSG):
+
+ Was versteht man unter Generizität?
+ Übungsziel: Generizitäts-Begriff
+
+
+
+Refinements
+
+Bevor wir die Operationen für TEXTe und BOOLs besprechen, wollen wir eine
+weitere wichtige Eigenschaft von ELAN diskutieren, nämlich die Namensgebung.
+Namen für Datenobjekte haben wir bereits kennengelernt. In ELAN ist es eben-
+falls möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen zu
+vergeben.
+
+
+Programm 10:
+
+ INT VAR a, b, x;
+ einlesen von a und b;
+ vertauschen von a und b;
+ vertauschte werte ausgeben.
+
+ einlesen von a und b:
+ get (a);
+ get (b).
+
+ vertauschen von a und b:
+ x := a;
+ a := b;
+ b := x.
+
+ vertauschte werte ausgeben:
+ put (a);
+ put (b).
+
+Dies ist das gleiche Programm wie das 9. Beispielprogramm. Für den Namen
+'einlesen von a und b' werden die Anweisungen 'get (a); get (b)' vom
+ELAN-Übersetzer eingesetzt. Man kann also die ersten vier Zeilen des
+Programms als eigentliches Programm ansehen, wobei die Namen durch die
+betreffenden Anweisungen ersetzt werden. Eine solche Konstruktion wird in
+ELAN Refinement genannt. Was wird dadurch erreicht?
+
+Durch die sinnvolle Verwendung von Refinements wird ein Programm im Programm
+und nicht in einer separaten Beschreibung dokumentiert. Weiterhin kann ein
+Programm "von oben nach unten" ("top down") entwickelt werden: wir haben das
+obige - zugegeben einfache - Beispielprogramm in drei Teile zerlegt und
+diese durch Namen beschrieben. Bei der Beschreibung von Aktionen durch Namen
+sagen wir, was wir machen wollen und nicht wie, denn wir brauchen uns auf
+dieser Stufe der Programmentwicklung um die Realisierung der Refinements
+(noch) keine Sorgen zu machen. Das erfolgt erst, wenn wir genauer definieren
+müssen, wie das Refinement programmiert werden muß. Dabei können wir
+wiederum Refinements verwenden usw., bis wir auf eine Ebene "herunterge-
+stiegen" sind, bei dem eine (jetzt: Teil-) Problemlösung sehr einfach ist
+und wir sie direkt hinschreiben können. Wir beschäftigen uns also an jedem
+Punkt der Problemlösung nur mit einem Teilaspekt des gesamten Problems.
+Zudem sieht man - wenn die Refinements einigermaßen vernünftig verwendet
+werden - dem Programm an, wie die Problemlösung entstanden ist.
+
+Die Verwendung von Refinements hat also eine Anzahl von Vorteilen. Schauen
+wir uns deshalb an, wie die Refinements formal verwandt werden müssen. Das
+"Hauptprogramm" wird durch einen Punkt abgeschlossen, falls ein Refinement
+folgt. Ein Refinement besteht aus der Nennung des Refinement-Namens, der
+von einem Doppelpunkt gefolgt sein muß. In einem Refinement kann eine
+Anweisung oder mehrere - durch Semikolon getrennt - stehen. Das Refinement
+wird durch einen Punkt abgeschlossen.
+
+Refinements können auch dort verwendet werden, wo ein Wert erwartet wird,
+z.B. in einem Ausdruck oder einer 'put'-Anweisung. In diesem Fall muß das
+Refinement natürlich einen Wert liefern. Wie macht man das? Eine Möglichkeit
+ist, daß im Refinement ein Ausdruck geschrieben wird, der einen Wert als
+Resultat liefert.
+
+
+Programm 11:
+
+ INT VAR a :: 1, b :: 2, c :: 3;
+ put (resultat).
+
+ resultat:
+ (a * b + c) ** 3.
+
+Eine Zuweisung liefert - wie bereits erwähnt - kein Resultat. Es ist auch
+erlaubt, ein Refinement mit mehreren Anweisungen zu schreiben, das einen Wert
+liefert. Allgemeine Regel: die letzte Anweisung eines Refinements bestimmt,
+ob ein Refinement einen Wert liefert - und wenn ja, von welchen Datentyp.
+
+
+
+BOOLesche Operationen
+
+Für BOOLesche Datenobjekte gibt es einige Operatoren:
+
+ BOOL OP AND (BOOL CONST links, rechts)
+ BOOL OP OR (BOOL CONST links, rechts)
+ BOOL OP NOT (BOOL CONST operand)
+
+Der Operator AND liefert als Resultat die logische "und"-Verknüpfung (nur
+wenn beide Operanden den Wert TRUE haben ist das Resultat TRUE, sonst FALSE),
+OR ist das logische "oder" (nur wenn beide Operanden FALSE liefern, ist das
+Resultat FALSE, sonst TRUE) und die logische Negation NOT (als Resultat wird
+das "Gegenteil" geliefert).
+
+Ebenfalls wichtig sind die Vergleichs-Operatoren, die zwar keine BOOLeschen
+Operanden erwarten, aber ein BOOLesches Resultat liefern:
+
+ BOOL OP = (INT CONST links, rechts)
+ BOOL OP <> (INT CONST links, rechts)
+ BOOL OP < (INT CONST links, rechts)
+ BOOL OP <= (INT CONST links, rechts)
+ BOOL OP > (INT CONST links, rechts)
+ BOOL OP >= (INT CONST links, rechts)
+
+Diese Operatoren: = (gleich), <> (ungleich), < (kleiner), <= (kleiner
+gleich), > (größer), >= (größer gleich) gibt es auch noch für Operanden vom
+Datentyp REAL und TEXT. Da die Vergleichs-Operatoren ein BOOLesches Resultat
+liefern, kann man sie in BOOLeschen Ausdrücken verwenden. Zu beachten ist
+dabei die Priorität der Operatoren: die Vergleiche werden immer vor den
+Operatoren AND bzw. OR ausgeführt.
+
+
+Programm 12:
+
+ BOOL CONST kaufen;
+ kaufen := will ich AND NOT zu teuer.
+
+ will ich:
+ TEXT VAR produktname;
+ get (produktname);
+ produktname = "muesli" OR produktname = "vollkornbrot".
+
+ zu teuer:
+ INT VAR preis;
+ get (preis);
+ preis > 20.
+
+
+
+Aufgabe (HSG):
+
+ Welche BOOL-Werte ergeben sich?
+
+ a) TRUE AND FALSE e) TRUE AND TRUE OR TRUE
+ b) TRUE OR FALSE f) 10 < 3 AND 17 > 4
+ c) TRUE AND NOT FALSE g) 17 + 4 = 21 OR TRUE
+ d) NOT TRUE AND FALSE h) TRUE AND FALSE OR TRUE
+
+ Übungsziel: Boolesche Ausdrücke
+
+
+
+Abfragen
+
+BOOLesche Ausdrücke werden in einer speziellen Anweisung verwandt, der
+Abfrage:
+
+
+Programm 13:
+
+ INT VAR a, b;
+ get (a); get (b);
+ IF a > b
+ THEN vertausche a und b
+ END IF;
+ put (a); put (b).
+
+ vertausche a und b:
+ INT CONST x :: a;
+ a := b;
+ b := x.
+
+Das Refinement im THEN-Teil der bedingten Anweisung wird nur durchgeführt,
+wenn der BOOLesche Ausdruck ('a > b') den Wert TRUE liefert. Liefert er den
+Wert FALSE, wird die Anweisung, die der bedingten Anweisung folgt (nach END
+IF), ausgeführt. Programm 13 kann etwas anders geschrieben werden:
+
+
+Programm 14:
+
+ INT VAR a, b;
+ get (a); get (b);
+ IF a > b
+ THEN put (a);
+ put (b)
+ ELSE put (b);
+ put (a)
+ END IF.
+
+Der THEN-Teil wird wiederum ausgeführt, wenn die BOOLesche Bedingung
+erfüllt ist. Liefert sie dagegen FALSE, wird der ELSE-Teil ausgeführt.
+
+Die bedingte Anweisung gibt uns also die Möglichkeit, abhängig von einer
+Bedingung eine oder mehrere Anweisungen ausführen zu lassen. Dabei können
+im THEN- bzw. ELSE-Teil wiederum bedingte Anweisungen enthalten sein usw.
+Solche geschachtelten bedingten Anweisungen sollte man jedoch vermeiden,
+weil sie leicht zu Fehlern führen können (statt dessen durch Refinements
+realisieren). Man beachte auch die Einrückungen, die man machen sollte, um
+die "Zweige" besonders kenntlich zu machen.
+
+
+Aufgabe (HSG):
+
+ a) In welcher Reihenfolge werden Operatoren ausgewertet?
+ b) Reihenfolge der Auswertung von: a + b + c
+ c) INT VAR a, b, c;
+ ...
+ IF NOT a = 0 AND b = 0 THEN...
+ ergibt einen syntaktischen Fehler. Welchen?
+ d) Wie wird der BOOLesche Ausdruck ausgewertet?
+ INT VAR a :: 0, b :: 4;
+ ...
+ IF a = 0 AND b DIV a > 0
+ e) Warum ist
+ BOOL VAR ende :: TRUE;
+ ...
+ IF ende = TRUE
+ THEN...
+ Unsinn?
+
+ Übungsziel: Reihenfolge der Auswertung von Ausdrücken
+
+Bei Abfrageketten kann das ELIF-Konstrukt eingesetzt werden. (ELIF ist eine
+Zusammenziehung der Worte ELSE und IF). Anstatt
+
+ ...
+ IF bedingung1
+ THEN aktion1
+ ELSE IF bedingung2
+ THEN aktion2
+ ELSE aktion3
+ END IF
+ END IF;
+ ...
+
+kann man besser
+
+ ...
+ IF bedingung1
+ THEN aktion1
+ ELIF bedingung2
+ THEN aktion2
+ ELSE aktion3 END IF;
+ ...
+
+schreiben.
+
+Die bedingte Anweisung kann auch einen Wert liefern. In diesem Fall muß der
+ELSE-Teil vorhanden sein und jeder Zweig den gleichen Datentyp liefern
+(jeweils die letzte Anweisung muß einen Wert liefern).
+
+
+Aufgabe (HSG):
+
+ Was berechnen folgende (Teil-) Programme?
+
+ a) INT VAR a;
+ get (a);
+ put (wert).
+
+ wert:
+ IF a < 0
+ THEN -a
+ ELSE a
+ END IF.
+
+ b) INT VAR brutto, netto;
+ get (brutto);
+ berechne gehalt;
+ put ("mein gehalt:");
+ put (netto).
+
+ berechne gehalt:
+ IF jahresverdienst > 30 000 (* zu wenig? *)
+ THEN sonderabgabe
+ END IF;
+ netto := brutto - brutto DIV 100 * 20.
+
+ jahresverdienst:
+ brutto * 12.
+
+ sonderabgabe:
+ brutto := brutto - brutto DIV 100 * 30
+
+ c) INT VAR x;
+ ...
+ put (signum).
+
+ signum:
+ IF x > 0
+ THEN 1
+ ELSE kleiner gleich
+ END IF.
+
+ kleiner gleich:
+ IF x = 0
+ THEN 0
+ ELSE -1
+ END IF.
+
+
+
+TEXTe
+
+TEXT-Denoter haben wir bereits kennengelernt. Im folgenden Programm stellen
+wir die Wirkung einiger TEXT-Operationen vor.
+
+
+Programm 15:
+
+ TEXT VAR a, b, c;
+ a := "ELAN";
+ b := "-Programm";
+ c := a + b;
+ put (c)
+
+Der Operator
+
+ TEXT OP + (TEXT CONST links, rechts)
+
+liefert als Ergebnis einen TEXT, bei dem an den linken der rechte Operand
+angefügt wurde (Fachausdruck: "Konkatenation"). Weitere Operatoren:
+
+ TEXT OP CAT (TEXT VAR ziel, TEXT CONST dazu)
+ TEXT OP * (INT CONST i, TEXT CONST a)
+ TEXT OP SUB (TEXT CONST t, INT CONST pos)
+
+Der Operator CAT fügt an einen TEXT einen zweiten an ('a CAT b' wirkt wie
+'a := a + b'). Mit dem '*'-Operator kann man einen TEXT vervielfältigen
+(Beispiel: 17 * "--"), während man mit SUB ein Zeichen aus einem TEXT her-
+ausholen kann (Beispiel: "ELAN" SUB 3 liefert "A").
+
+Die meisten TEXT-Operationen sind als Prozeduren realisiert, weil mehr als
+zwei Operanden benötigt werden. Die Wirkung einiger Operationen geben wir in
+kurzen Kommentaren an:
+
+ TEXT PROC subtext (TEXT CONST t, INT CONST von)
+ (* rechter Teiltext von 't' von der Position 'von' bis Ende *)
+
+ TEXT PROC subtext (TEXT CONST t, INT CONST von, bis)
+ (* Teiltext von 't' von der Position 'von' bis 'bis' *)
+
+ PROC change (TEXT VAR t, TEXT CONST old, new)
+ (* Ersetzung von 'old' in 'new' im TEXT 't' *)
+
+ INT PROC length (TEXT CONST t)
+ (* Anzahl Zeichen von 't' *)
+
+ INT PROC pos (TEXT CONST t, muster)
+ (* Die Position des ersten Auftretens von 'muster' in 't' *)
+
+Die Vergleichs-Operatoren für TEXTe arbeiten bei dem Vergleich nach der
+alphabetischen Reihenfolge ('"a" < "b"' liefert TRUE). Dabei definiert ELAN
+nur die Reihenfolge innerhalb der kleinen und großen Buchstaben und Ziffern.
+Das Leerzeichen ("#ib#blank#ie#") ist jedoch stets das "kleinste" Zeichen.
+Wie diese "Zeichenblöcke" und die restlichen Zeichen angeordnet sind, wurde
+nicht spezifiziert. Ob '"a" < "Z"' TRUE oder FALSE liefert, wurde also nicht
+festgelegt und ist somit rechnerspezifisch. Anmerkung: Im EUMEL-Betriebs-
+system wird der ASCII-Zeichencode, DIN 66 003 mit Erweiterungen verwandt.
+Die folgenden Vergleiche sind alle TRUE:
+
+ "otto" = "otto"
+ "a" < "z"
+ "Adam" < "Eva"
+ "hallo" < "hallu"
+ "hallo" < "hallo "
+ length ("ha") = 2
+ subtext ("ELAN-Programmierung", 14) = "ierung"
+
+
+Aufgabe (HSG):
+
+ Gib die Realisierung von folgenden vorgegebenen Prozeduren und Opera-
+ toren an:
+ a) TEXT PROC subtext (TEXT CONST t, INT CONST von) durch
+ TEXT PROC subtext (TEXT CONST t, INT CONST von, bis)
+ b) OP CAT (TEXT VAR a, TEXT CONST b) durch ':=' und '+'
+ c) TEXT OP SUB (TEXT CONST t, INT CONST p) durch 'subtext'
+
+ Übungsziel: Lernen einiger vorgegebener TEXT-Operationen
+
+
+
+Die Wiederholungs-Anweisung
+
+Wiederholungs-Anweisungen ermöglichen es uns, Anweisungen wiederholt - meist
+in Abhängigkeit von einer Bedingung - ausführen zu lassen. Darum wird die
+Wiederholungs-Anweisung oft auch #ib#Schleife#ie# genannt, die in ihr ent-
+haltenen Anweisungen #ib#Schleifenrumpf#ie#. Die Schleife von ELAN baut auf
+einem Basis-Konstrukt auf:
+
+ REP
+ anweisungen
+ END REP
+
+Diese Anweisungsfolge realisiert eine sogenannte "Endlosschleife", weil nicht
+spezifiziert wird, wann die Schleife beendet werden soll.
+
+Bei der abweisenden Schleife wird die Abbruchbedingung an den Anfang der
+Schleife geschrieben:
+
+ WHILE boolesche bedingung REP
+ anweisungen
+ END REP
+
+Bei jedem erneuten Durchlauf durch die Schleife wird überprüft, ob der
+BOOLesche Ausdruck den Wert TRUE liefert. Ist das nicht der Fall, wird mit
+der nächsten, auf die Schleife folgenden Anweisung mit der Bearbeitung fort-
+gefahren. Die Schleife wird abweisende Schleife genannt, weil der Schleifen-
+rumpf nicht ausgeführt wird, wenn die Bedingung vor Eintritt in die Schleife
+bereits FALSE liefert.
+
+Anders verhält es bei der nicht abweisenden Schleife:
+
+ REP
+ anweisungen
+ UNTIL boolesche Bedingung END REP
+
+Hier wird der Schleifenrumpf auf jeden Fall einmal bearbeitet. Am Ende des
+Rumpfes wird die BOOLesche Bedingung abgefragt. Liefert diese den Wert FALSE,
+wird die Schleife erneut abgearbeitet. Liefert die Bedingung den Wert TRUE,
+wird die Schleife abgebrochen und mit der ersten Anweisung hinter der
+Schleife in der Bearbeitung fortgefahren.
+
+Bei beiden Arten der Wiederholungs-Anweisung ist es wichtig, daß Elemente
+der BOOLeschen Bedingung in der Schleife verändert werden, damit das
+Programm terminieren kann, d.h. die Schleife abgebrochen wird.
+
+Eine Endlos-Schleife wird bei der Zählschleife meist nicht vorkommen:
+
+ FOR i FROM anfangswert UPTO endwert REP
+ anweisungen
+ END REP
+
+Zählschleifen werden eingesetzt, wenn die genaue Anzahl der Schleifendurch-
+läufe bekannt ist. Hier wird eine Laufvariable verwendet (in unserem Bei-
+spiel 'i': sie muß mit INT VAR deklariert werden), die die INT-Werte von
+'anfangswert' bis 'endwert' in Schritten von '1' durchläuft. Diese Schleife
+zählt "aufwärts". Wird anstatt UPTO das Schlüsselwort DOWNTO verwendet, wird
+mit Schritten von -1 "abwärts" gezählt. Beispiel:
+
+ FOR i FROM endwert DOWNTO anfangswert REP
+ ...
+
+Für ein Beispielprogramm stellen wir uns die Aufgabe, aus TEXTen das Auf-
+treten des Buchstabens "e" herauszufinden. Die TEXTe sollen vom Eingabe-
+medium solange eingelesen werden, bis wir den TEXT "00" eingeben.
+
+
+Programm 16:
+
+ INT VAR anzahl e :: 0;
+ TEXT VAR wort;
+ REP
+ get (wort);
+ zaehle e im wort
+ UNTIL wort = "00" END REP;
+ put (anzahl e).
+
+ zaehle e im wort:
+ INT VAR i;
+ FOR i FROM 1 UPTO length (wort) REP
+ IF das i te zeichen ist e
+ THEN anzahl e INCR 1
+ END IF
+ END REP.
+
+ das i te zeichen ist e:
+ (wort SUB i) = "e".
+
+
+Aufgabe (HSG):
+
+ Die Klammern in dem letzten Refinement sind notwendig. Warum?
+
+Bevor wir ein Programm einem Rechner zur Bearbeitung übergeben, sollten wir
+uns davon überzeugen, daß das Programm wirklich das leistet, was es soll.
+Eine der wichtigsten Bedingungen ist die Terminierung eines Programms, d.h.
+das Programm darf nicht in eine Endlosschleife geraten. Unser Beispielpro-
+gramm terminiert, wenn beide Schleifen terminieren: die obere Schleife
+terminiert durch das Endekriterium, während die zweite Schleife automatisch
+durch die Zählschleife begrenzt wird. Das Programm wird also auf jeden Fall
+beendet (kann in keine Endlosschleife geraten), falls das Endekriterium ein-
+gegeben wird.
+Interessant sind dabei immer "Grenzfälle", wie z.B. die Eingabe eines
+"leeren Textes", sehr lange TEXTe usw.
+
+
+Aufgabe (HSG):
+
+ Welche Fehler befinden sich in den folgenden Programmteilen?
+ a) INT VAR i;
+ FOR i FROM 1 UPTO i REP
+ tue irgendwas
+ END REP
+
+ b) BOOL CONST noch werte :: TRUE;
+ INT VAR i;
+ WHILE noch werte REP
+ get (i);
+ ...
+ IF i = O
+ THEN noch werte := FALSE
+ END IF
+ END REP
+
+ c) INT VAR anz berechnungen :: 1;
+ REP
+ lies eingabe wert;
+ berechnung;
+ drucke ausgabewert
+ UNTIL anz berechnungen > 10 END REP.
+
+ d) INT VAR anz berechnungen;
+ WHILE anz berechnungen <= 10 REP
+ lies eingabewert;
+ berechnung;
+ drucke ausgabewert;
+ anz berechnungen INCR 1
+ END REP.
+
+ e) INT VAR n := 1, summe;
+ summe der ersten 100 zahlen.
+
+ summe der ersten 100 zahlen:
+ WHILE n < 100 REP
+ summe := summe + n;
+ n INCR 1
+ END REP.
+ (* Achtung: 2 Fehler! (Vorwarnen ist feige) *)
+
+ f) INT VAR n := 1;
+ REP
+ INT VAR summe := 0;
+ summe := summe + n;
+ n INCR 1
+ UNTIL n = 100 END REP
+ (* Achtung: 2 Fehler! *)
+
+ Übungsziel: Arbeiten mit Schleifen
+
+
+Das Programm 16 können wir etwas besser formulieren. Dazu wollen wir uns
+aber eine etwas andere Aufgabe stellen: wie viele Leerzeichen sind in einem
+Text? Zur Lösung dieser Aufgabe sollten wir den Text nicht wortweise ein-
+lesen, sondern zeilenweise. Dazu verwenden wir die Prozedur
+
+ PROC get (TEXT VAR t, INT CONST max length)
+
+die einen TEXT 't' mit maximal 'max length' Zeichen einliest. Auf dem
+EUMEL-System gibt es dafür auch die Prozedur 'getline'.
+
+
+Programm 17:
+
+ INT VAR anzahl blanks :: 0;
+ REP
+ lies zeile ein;
+ zaehle blanks
+ UNTIL zeile hat endekriterium END REP.
+
+ lies zeile ein:
+ TEXT VAR zeile;
+ get (zeile, 80).
+
+ zaehle blanks:
+ INT VAR von :: 1;
+ WHILE zeile hat ab von ein blank REP
+ anzahl blanks INCR 1;
+ von auf blank position setzen
+ END REP.
+
+ zeile hat ab von ein blank:
+ pos (zeile, " ", von) > 0.
+
+ von auf blank position setzen:
+ von := pos (zeile, " ", von).
+
+ zeile hat endekriterium:
+ pos (zeile, "00") > 0.
+
+
+Aufgabe (TSW):
+
+ Das Programm 17 enthält (mindestens) zwei Fehler. Finden Sie diese bitte
+ heraus.
+
+ Übungsziel: Finden von Programmierfehlern.
+
+
+Aufgabe (HSG):
+
+ a) Welche Werte liefern folgende Ausdrücke für die Textvariable
+ TEXT VAR t :: "Das ist mein Text"
+ a1) pos (t, "ist")
+ a2) pos (t, "ist", 5)
+ a3) length (t)
+ a4) subtext (t, 14)
+ a5) subtext (t, 14, 17)
+
+ b) Welche Werte liefern folgende Ausdrücke für die Textkonstanten
+ TEXT CONST text :: "ELAN-Programm",
+ alphabet :: "abcde...xyz"
+ b1) 3 * text
+ b2) length ("mein" + text + 3 * "ha")
+ b3) 3 * "ha" < text
+ b4) pos (text, alphabet SUB 1)
+ b5) pos (text, subtext (alphabet, 7, 7))
+
+ c) Schreibe in anderer Form:
+ c1) subtext (text, 7, 7)
+ c2) change (text, "alt", "neu")
+ c3) INT VAR laenge :: length (text);
+ IF subtext (text, laenge, laenge) =...
+ c4) IF NOT (text = "aha")
+ THEN aktion 1
+ ELSE aktion 2
+ END IF
+
+ Übungsziel: TEXT-Ausdrücke und Prozeduren
+
+
+
+Die Repräsentation von Datentypen
+
+Wie bereits erwähnt, sind Datentypen Klassen von Objekten der realen Umwelt.
+Die Objekte eines Datentyps müssen in den Speicher eines Rechners abgebildet
+werden. Die Darstellung eines Objekts im Rechner wird Repräsentation genannt.
+Aus organisatorischen Gründen versucht man, immer feste, gleich große Ein-
+heiten für die Objekte eines Datentyps zu verwenden. Durch die Begrenzung auf
+feste Speicherplatzeinheiten ist der Wertebereich beschränkt. Diese Grenzen
+hat man beim Programmieren zu beachten.
+
+Beim Datentyp BOOL spielt die Repräsentation nur insoweit eine Rolle, daß
+man die zwei möglichen Werte mehr oder weniger speicheraufwendig realisieren
+kann. Eine Einschränkung des Wertebereichs gibt es nicht.
+
+Bei INTs ist jedoch eine Einschränkung des Wertebereichs gegeben. Für die
+Repräsentation von INTs sind Einheiten von 16, 32 Bit u.a.m. gebräuchlich.
+Es existiert die Möglichkeit, den größten INT-Wert mit Hilfe von
+
+ maxint
+
+zu erfragen. Z.B. ist 'maxint' für EUMEL-Systeme z.Zt. 32 767. Der kleinste
+INT-Wert ist oft nicht ' - maxint' (im EUMEL-System kann er unter 'minint'
+angesprochen werden). Übersteigt ein Wert 'maxint', gibt es eine Fehler-
+meldung 'overflow', im andern Fall 'underflow'.
+
+REALs sind noch schwieriger. Durch die endliche Darstellung der Mantisse
+treten "Lücken" zwischen zwei benachbarten REALs auf. Deshalb ist bei Ver-
+wendung von REALs immer mit Repräsentationsfehlern zu rechnen. Dieses Thema
+der "Rundungsfehler" wollen wir hier jedoch nicht weiter vertiefen. Auf
+jeden Fall gibt es aber auch einen größten REAL-Wert
+
+ maxreal
+
+Bei TEXTen gibt es zwei Repräsentations-Schwierigkeiten. Einerseits werden
+TEXTe durch "irgendeinen" Code im Rechner repräsentiert, der z.B. bei Ver-
+gleichen verwendet wird. ELAN-Compiler auf Rechenanlagen mit unterschied-
+lichen Zeichencodes können daher unterschiedliche Ergebnisse liefern.
+Andererseits ist in ELAN nicht definiert, wie viele Zeichen maximal in einen
+TEXT passen, was ebenfalls vom Rechner bzw. von einem ELAN-Compiler abhängt.
+Auf dem EUMEL-System kann die maximale Anzahl Zeichen eines TEXTs durch
+'maxtext length' erfragt werden. Sie ist z.Z. '32 000'.
+
+
+
+Ein- und Ausgabe
+
+Wie Datenobjekte - auf einfache Weise - auf einem Ausgabemedium ausgegeben
+werden können, haben wir bereits geschildert (Prozedur 'put'). Die Ausgabe
+erfolgt solange auf einer Zeile, bis ein auszugebender Wert nicht mehr auf
+eine Zeile paßt. In diesem Fall wird die Ausgabe in die nächste Zeile pla-
+ziert. Zwischen den einzelnen Werten auf einer Zeile wird jeweils ein Blank
+Zwischenraum gelassen, um die Ausgaben voneinander zu trennen. Mit folgenden
+Prozeduren kann man die Ausgabe flexibel gestalten:
+
+ PROC line (* bewirkt einen Zeilenvorschub *)
+
+ PROC line (INT CONST anzahl) (* bewirkt 'anzahl' Zeilenvorschübe *)
+
+ PROC page (* bewirkt einen Seitenvorschub auf
+ einem Drucker oder löscht den Bild-
+ schirm und positioniert in die linke
+ obere Ecke *)
+
+ PROC putline (TEXT CONST zeile) (* gibt 'zeile' auf dem Bildschirm aus
+ und positioniert auf die nächste
+ neue Zeile *)
+
+ PROC cursor (INT CONST reihe, spalte) (* Positioniert die Schreibmarke
+ auf dem Bildschirm in die an-
+ gegebene Position *)
+
+Die Prozedur 'get' holt Eingaben vom Eingabemedium. Ein Element der Eingabe
+wird dabei durch ein Blank vom nächsten getrennt. Einige weitere Eingabe-
+Prozeduren:
+
+ PROC get (TEXT VAR t, TEXT CONST delimiter) (* die nächste Eingabe wird
+ nicht von einem Blank
+ begrenzt, sondern durch
+ 'delimiter' *)
+
+ TEXT PROC get (* dient zum Initialisieren *)
+
+ PROC inchar (TEXT VAR zeichen) (* wartet solange, bis ein Zeichen vom
+ Bildschirm eingegeben wird *)
+
+ TEXT PROC incharety (* Versucht ein Zeichen vom Bildschirm
+ zu lesen. Ist kein Zeichen vor-
+ handen, wird "" geliefert *)
+
+ PROC editget (TEXT VAR line) (* Bei der Eingabe kann 'line' editiert
+ werden *)
+
+ PROC get cursor (INT VAR zeile, spalte) (* Informationsprozedur, wo die
+ Schreibmarke aktuell steht *)
+
+
+
+Konvertierungen
+
+Manchmal ist es notwendig, eine Datentyp-Wandlung für ein Objekt vorzunehmen.
+Die Wandlungen von einem INT- bzw. einen REAL-Wert in einen TEXT und umge-
+kehrt sind relativ unkritisch:
+
+ TEXT PROC text (INT CONST value)
+ TEXT PROC text (REAL CONST value)
+ INT PROC int (TEXT CONST number)
+ REAL PROC real (TEXT CONST number)
+
+Aber bei der folgenden Prozedur 'int' gehen im allgemeinen Fall Informationen
+verloren (es wird abgeschnitten):
+
+ INT PROC int (REAL CONST value)
+ REAL PROC real (INT CONST value)
+
+Zusätzlich steht eine Informationsprozedur 'last conversion ok' zur Ver-
+fügung, die den Wert TRUE liefert, falls die letzte Konversion fehlerfrei
+war:
+
+ BOOL PROC last conversion ok
+
+Solche Abfragen sind notwendig, weil die Konversionsroutinen bei falschen
+Parameterwerten (z.B. 'int (maxreal)') nicht mit einer Fehlermeldung ab-
+brechen. Als Beispiel zeigen wir ein Programm zum Einlesen von Werten, von
+denen man nicht weiß, ob sie INT oder REAL sind. Darum kann auch nicht die
+'get'-Prozedur für INT oder REAL verwandt werden:
+
+
+Programm 18:
+
+ TEXT VAR eingabe element;
+ REP
+ get (eingabe element);
+ wert nach intwert oder realwert bringen;
+ berechnung
+ UNTIL ende ENDREP.
+
+ wert nach intwert oder realwert bringen:
+ IF pos (eingabe element, ".") > 0
+ THEN REAL VAR realwert :: real (eingabe element)
+ ELSE INT VAR intwert :: int (eingabe element)
+ END IF;
+ IF NOT last conversion ok
+ THEN put ("Fehler bei Konvertierung:" + eingabe element);
+ line
+ END IF.
+
+ berechnung:
+ ...
+
+