1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
#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.
|