#limit (11.0)##pagelength (16.5)##block# #start (2.0,0.0)# #page (165)# #headodd# #center#EUDAS#right#% #end# #headeven# %#center#EUDAS #end# #center#1 15 Anweisungen in ELAN 15.1 Variablen und Zuweisungen Im vorigen Kapitel haben wir Ausdrücke in ELAN kennengelernt. Der Wert eines Ausdrucks wird bei jeder Verwendung erneut berechnet. Wenn wir den Wert eines Ausdrucks aufbewahren wollen, müssen wir ihn schon in eine EUDAS-Datei schreiben. Oft tritt jedoch die Notwendigkeit auf, Werte zu merken, ohne sie in einer Datei zu speichern. Beispiel dafür ist ein Zählvorgang im Druckmuster. In jedem Wiederholungsteil muß der dazukommende Wert zum bisherigen, aufsummierten und aufbewahrten Wert addiert werden. Das Zwischenergebnis der Zählung muß also irgendwo ge­ speichert werden. #on("b")#Variablen#off("b")# Zu diesem Zweck gibt es Variablen. Sie sind ähnlich wie Felder in einer Datei. Ihre Existenz ist jedoch unabhängig von einer Datei. Außerdem sind sie zu Anfang nicht einfach leer, sondern haben einen undefinierten Wert. Variablen müssen im Programm definiert werden. Sie existieren dann während der Ausführung dieses Programms und gehen an­ schließend verloren. Zu Beginn des Programms sind sie, wie schon gesagt, undefiniert. Eine Variable muß immer einen Typ haben. Dieser Typ ist für die Lebensdauer der Variable unveränderlich. Die Variable kann natürlich nur Werte dieses Typs annehmen. Eine Variablendefinition (oder auch -deklaration) besteht aus der Angabe eines Typs, dem Schlüsselwort VAR und einem freige­ wählten Namen. Wie schon bei den Refinements darf ein solcher Name nur aus Kleinbuchstaben (keine Umlaute) und eventuell Zif­ fern bestehen. Dagegen darf der Name Leerzeichen enthalten. Beispiel: INT VAR zaehler; TEXT VAR feldname; REAL VAR mein ergebnis 1; Das Semikolon am Ende beschließt die Definition. Die Lebensdauer einer Variablen hängt davon ab, an welcher Stelle sie definiert ist. Eine Variable, die im Druckmuster im Initia­ lisierungsteil definiert ist, behält ihren Wert für die gesamte Dauer des Druckvorgangs. Eine Variable in einem Abschnitt lebt dagegen nur für eine Abarbeitung dieses Abschnitts. Bei der nächsten Abar­ beitung ist sie wieder undefiniert. Das gleiche gilt für Kopier- und Änderungsmuster. Auch hier sind Variablen nur für die Dauer der Bearbeitung eines Satzes gültig. #on("b")#Zuweisung#off("b")# Um einer Variablen einen Wert zu geben, führt man eine #on ("i")#Zuweisung#off("i")# aus. Die Zuweisung wird durch Doppelpunkt und Gleich­ heitszeichen aneinandergeschrieben gekennzeichnet. Auf der linken Seite steht die Variable, auf der rechten Seite eine Ausdruck: zaehler := 1; Wie oben schließt das Semikolon die Anweisung ab. Nach der Aus­ führung hat die Variable den Wert 1. Der Wert vorher ist für die Zuweisung egal, er kann definiert oder undefiniert sein. Eine Variable kann in einem Ausdruck verwendet werden, indem man einfach den Namen hinschreibt. Der Ausdruck zaehler + 1 hat nach der obigen Zuweisung den Wert 2. Eine Variable muß bei der Verwendung definiert sein, sonst können beliebige Fehler ent­ stehen. Es muß also vor der ersten Verwendung ausdrücklich eine Zuweisung erfolgt sein. Da Variablen in Ausdrücken verwendet werden können und Ausdrücke auf der rechten Seite einer Zuweisung stehen, ist folgen­ de Konstruktion möglich: zaehler := zaehler + 1; Diese Zeile bewirkt, daß der Wert der Variable um 1 erhöht wird. Zuerst wird bei der Zuweisung der Wert des Ausdrucks auf der rech­ ten Seite bestimmt. Zu diesem Zeitpunkt habe die Variable bei­ spielsweise den Wert 1. Der Ausdruck hat dann den Wert 2 (1+1). Dieser Wert wird der neue Wert der Variablen. Bei der nächsten Ausführung würde sich der gleiche Vorgang wiederholen, so daß die Variable anschließend den Wert 3 hat. Auch bei der Zuweisung gilt natürlich, daß die Variable auf der linken Seite den gleichen Datentyp haben muß wie der Ausdruck auf der rechten Seite. #on("b")#Initialisierung#off("b")# Sie können Variablendeklaration und Zuweisung auch miteinander verknüpfen, so daß die Variable gleich zu Anfang einen Wert erhält: INT VAR zaehler := 0; Dieses Verfahren ist eine gute Vorsichtsmaßregel, damit Sie keine undefinierten Variablen verwenden. #on("b")#Inkrement#off("b")# Da der Fall so häufig auftritt, daß der Wert einer Vari­ ablen um einen bestimmten Wert erhöht wird (bei allen Zählvorgän­ gen), gibt es auch dafür eine Abkürzung, und zwar die beiden Ope­ ratoren INCR und DECR. zaehler INCR 1; mein ergebnis 1 DECR 24.4; Die Operatoren sind für REALs und INTs definiert. INCR erhöht um einen Betrag, DECR erniedrigt. Auf der rechten Seite darf wieder ein beliebiger Ausdruck stehen. Für TEXTe gibt es eine ähnliche Abkürzung, allerdings nur für die Addition (Verkettung). Hier heißt der Operator CAT. Die beiden folgenden Zeilen haben die gleiche Bedeutung: feldname := feldname + "."; feldname CAT "."; 15.2 Weitere Konstruktionen #on("b")#IF#off("b")# Die Ihnen bereits bekannte IF-Konstruktion dient nicht nur dazu, Werte zu liefern, sondern steuert auch die Abarbeitung von beliebigen Anweisungen. Diese Anweisungen können Kopier- und Änderungsanweisungen sein (s. Kapitel 11), oder die oben beschrie­ benen Zuweisungen. In einem Teil der IF-Konstruktion können auch mehrere Anwei­ sungen stehen. Diese müssen dann jedoch unbedingt durch Semiko­ lon getrennt sein. Mehrere Anweisungen hintereinander haben ein­ fach die Bedeutung der Ausführung in der notierten Reihenfolge. Als drittes kann auch der ELSE-Teil weggelassen, da nicht in jedem Fall ein Ergebnis erwartet wird. Falls die Bedingung nicht zutrifft, muß nicht unbedingt etwas ausgeführt werden. IF zaehler > 0 THEN zaehler DECR 1; mein ergebnis 1 INCR wert ("zaehlfeld") END IF; Auch diese IF-Konstruktion kann wieder geschachtelt werden. Für viele Fälle gibt es jedoch einen ELIF-Teil, der die Verschachtelung erspart: IF f ("m/w") = "m" THEN maenner INCR 1 ELIF f ("m/w") = "w" THEN frauen INCR 1 ELSE zweifelhaft INCR 1 END IF; Der ELIF-Teil beinhaltet noch einmal einen Test. Dieser Test wird jedoch nur dann durchgeführt, wenn die erste Bedingung falsch war. Gibt es noch mehr Wahlmöglichkeiten, können Sie beliebig viele ELIF-Teile benutzen. Beachten Sie, daß die letzte Anweisung in einem Teil der IF- Konstruktion nicht unbedingt ein folgendes Semikolon haben muß (das Semikolon soll nur trennen). Ein Semikolon an dieser Stelle kann aber auch nicht schaden. #on("b")#Werteliefernde Programme#off("b")# Nicht nur Ausdrücke können Werte lie­ fern, sondern auch ganze Anweisungsfolgen. Dies ist eine Erweite­ rung der werteliefernden IF-Konstruktion. Sie können dies für Ab­ kürzungen oder Refinements ausnutzen. endergebnis : gesammelte zeichen CAT "."; gesammelte zeichen . In diesem Beispiel werden in einer Textvariable bestimmte Zeichen gesammelt. Zum Schluß soll ein Punkt angefügt werden und dieser Text dann als Ergebnis des Refinements geliefert werden. Damit eine Anweisungsfolge einen Wert liefert, muß am Ende der Anweisungsfolge ein Ausdruck stehen. Der Wert des Ausdrucks nach Abarbeitung der Anweisungen ist dann der Wert der Anwei­ sungsfolge. Allerdings kann man den gleichen Wert oft verschieden aus­ drücken. Folgendes Refinement hat die gleiche Wirkung wie oben: endergebnis : gesammelte zeichen + "." . In manchen Fällen ist eine Formulierung als werteliefernde Anwei­ sungsfolge jedoch übersichtlicher. #on("b")#Beispiel#off("b")# Zum Abschluß dieses Kapitels wollen wir als Beispiel eine statistische Auswertung einer Zahlenreihe als Druckmuster formu­ lieren. Gegeben sei eine Datei mit folgenden Feldern: "Meßwert 1" "Meßwert 2" Wir wollen als Ergebnis Mittelwert und Standardabweichung der beiden Meßwerte ausdrucken. Dazu dient das Druckmuster auf der folgenden Seite. Im Initialisierungsteil des Druckmusters werden die notwendi­ gen Variablen definiert und initialisiert. Beachten Sie hier, daß in einer Definition mehrere Variablen durch Komma getrennt aufgeführt werden können, wenn sie den gleichen Typ haben. Im Wiederholungsteil müssen dann jeweils die Zwischensummen aktualisiert werden. Da mit der Funktion 'wert' eine relativ auf­ wendige Umwandlung verbunden ist, wird der Wert des jeweiligen Feldes erst einmal in einer Variable zwischengespeichert, da er mehrmals benötigt wird. Diese Zwischenspeicherungsvariable muß nicht initialisiert werden Im Nachspann werden dann die Ergebnisse gedruckt. Die Formeln sind jeweils als Abkürzungen definiert. Die Funktion 'zahltext' sorgt dafür, daß die Werte mit drei Nachkommastellen (gerundet) aufge­ führt werden. Da die Formeln relativ komplex sind, werden sie auf mehrere Zeilen verteilt (in ELAN hat das Zeilenende keine Bedeutung). %% REAL VAR %% messwert, %% summe 1 := 0.0, quadratsumme 1 := 0.0, %% summe 2 := 0.0, quadratsumme 2 := 0.0; %% INT VAR anzahl := 0; % WIEDERHOLUNG %% anzahl INCR 1; %% messwert := wert ("Meßwert 1"); %% summe 1 INCR messwert; %% quadratsumme 1 INCR messwert * messwert; %% messwert := wert ("Meßwert 2"); %% summe 2 INCR messwert; %% quadratsumme 2 INCR messwert * messwert; % NACHSPANN &anz Meßwerte. Meßwert 1 Meßwert 2 Mittelwert &&mw1&&&& &&mw2&&&& Standardabweichung &&st1&&&& &&st2&&&& % ABKUERZUNGEN &mw1 : zahltext (summe 1 / real (anzahl), 3) . &mw2 : zahltext (summe 2 / real (anzahl), 3) . &st1 : zahltext (sqrt ((quadratsumme 1 - summe 1 * summe 1 / real (anzahl)) / real (anzahl - 1)), 3) . &st2 : zahltext (sqrt ((quadratsumme 2 - summe 2 * summe 2 / real (anzahl)) / real (anzahl - 1)), 3) . Mit entsprechenden Formeln können Sie dieses Beispiel für Ihre eigenen Statistiken erweitern. Die Beispiele der letzten beiden Ka­ pitel sollten Ihnen genügend Anregungen dafür gegeben haben.