Reference
1. Die ersten Schritte
Machen Sie sich als erstes mit den Grundbefehlen in
AdaLogo vertraut. Gehen Sie dazu auf Examples/befehle.adl
und führen Sie die Befehle im Editor-Fenster durch
"step by step" aus. Lesen Sie dazu die Kommentaren
und beobachten Sie was die Schildkröte macht.
Alle Grundbefehle, die direkt Auswirkungen auf
die Schildkröte haben, sind:
forward(100);
move_to(200,200);
new_line;
pen_up;
pen_down;
put_line("hallo");
put(100);
turtle_reset;
turn(90);
turn_to(225);
Natürlich kann innerhalb der Klammer eine beliebige
ganze Zahl stehen, ja sogar noch mehr. AdaLogo kann auch
rechnen, dazu kommen wir jedoch im Punkt 3.
put und put_line akzeptieren außer Zahlenausdrücke
(siehe 3.) und logische Operationen
(siehe 4.) auch Zeichenketten. In einer Zeichenkette
dürfen beliebige Buchstaben auftauchen außer Anführungszeichen
("). put und put_line werten diese Ausdrücke aus
und geben die Auswertung in der Konsole aus. new_line; schreibt
eine neue leere Zeile in die Konsole.
Mit diesen Befehlen können Sie bereits den ersten Buchstaben
Ihres Namen zeichnen. Versuchen Sie es doch einmal!
2. Der "Rahmen"
Wählen Sie bitte Examples/template.adl aus.
Bevor Sie beginnen, sollten Sie doch mit folgenden Sprachkonstrukten
vertraut sein:
3. Der "Taschenrechner"
Sie können nicht nur forward(100); mit einer einfachen ganzen Zahl
schreiben, sondern Sie können mit AdaLogo auch Berechnungen anstellen. Anstelle
von 100 können Sie auch Folgendes schreiben, wobei x und y Element der ganzen
Zahlen sein darf.
- -x bildet das Inverse zu x.
- x + y Addition
- x - y Subtraktion
- x * y Multiplikation
- x / y (Vorsicht, y ungleich 0) Division
- x mod y (Vorsicht, y ungleich 0)
Modulo
- x rem y (Vorsicht, y ungleich 0) Remainder
- turtle_x liefert den x-Wert von Stelle, an der sich die Schildkröte befindet.
- turtle_y liefert den y-Wert von Stelle, an der sich die Schildkröte befindet.
- turtle_dir liefert die Richtung, in der die Schildkröte gerade zeigt.
- min(x,y) liefert die kleinere Zahl von x und y.
- max(x,y) liefert die größere Zahl von x und y.
- random(x,y) liefert eine zufällige Zahl zwischen x und y, wobei
nicht zwingend y > x gelten muss. Die untere Grenze gehört dazu, die obere jedoch nicht.
Z.B. liefert random(2,6) zufällige Zahlen von der Menge {2,3,4,5}.
AdaLogo rechnet dabei "Punkt vor Strich". * / mod und rem binden "stärker"
und werden zuerst ausgerechnet, danach kommen + und - . Inversebildung
bindet am "stärksten".
Wollen Sie bei einem Ausdruck a + b * c, dass a + b zuerst ausgerechnet wird,
so müssen Sie für die richtige Klammerung sorgen:
(a + b) * c
Natürlich ist es möglich diese Operationen auf der Menge der ganzen Zahlen
beliebig zu kombinieren.
Anstelle von x und y ist es auch möglich Variabel-Namen aufzurufen, falls
diese vorher im Deklarationsbereich definiert wurden. Dazu siehe Punkt 7.
4. Logik
AdaLogo unterstützt die zweiwertige Logik mit true und false.
Logische Werte a und b können mit folgenden Operationen verknüpft werden:
- a or b gibt true zurück, falls a oder b true ist, andernfalls
false. (siehe Wikipedia)
- a and b gibt true zurück, falls a und b true ist, andernfalls
false. (siehe Wikipedia)
- not a bildet das Inverse zu a.
Zu beachten ist, dass not am "stärksten" bindet, danach and
und dann or. Möchten Sie diese Bindung anders, so muss entsprechend
Klammer gesetzt werden.
Hier Beispiele:
not(a or b) and c
-- Zuerst a or b, dann not und danach and.
(a or not b) and (c or d)
-- Zuerst not, danach beide Klammer und dann and.
Anstelle von a und b ist es auch möglich Variabel-Namen aufzurufen, falls
diese vorher im Deklarationsbereich definiert wurden. Dazu siehe Punkt 7.
5. Vergleichsoperationen
In AdaLogo gibt es folgende Vergleichsoperationen. Verglichen werden x und y, wobei
diese die Bedingung aus 3. erfüllen müssen. Das Ergebnis ist true
oder false und entspricht die Definition von 4.
- a = b ergibt true falls a den gleichen Wert hat wie b, andernfalls false.
- a /= b ergibt true falls a nicht den gleichen Wert hat wie b, andernfalls false.
- a > b ergibt true falls a größer ist als b, andernfalls false.
- a >= b ergibt true falls a ist größer oder gleich b, andernfalls false.
- a < b ergibt true falls a kleiner ist als b, andernfalls false.
- a <= b ergibt true falls a ist kleiner oder gleich b, andernfalls false.
Ergebnisse von Vergleichsoperationen können in 4. als ein Logikausdruck verwendet werden.
Z.B. ist a < b or c >= d zulässig.
6. Sprachkonstrukte
Für "null", bedingte, wiederholte und Sprung-Anweisungen existieren folgende
Sprachelemente:
6.1 null;
null; - diese Anweisung macht und schlicht und einfach gar nichts.
Sie ist nur wichtig, um leere Prozeduren oder Konstrukte zu schreiben. In Ada(Logo)
wird oft nach mindestens einer Anweisung verlangt, falls Sie keine Anweisung ausführen
möchten, so benutzen Sie
null;
6.2 if
So sieht z.B. eine bedingte Anweisung mit if aus:
if a then
-- hier anweisungen1
elsif b then
-- hier anweisungen2
elsif c then
-- hier anweisungen3
else
-- hier anweisungen4
end if;
Der if-Teil mit Anweisungen sowie end if; muss genau 1 Mal da sein.
Der elsif-Teil mit Anweisungen kann 0 Mal, 1 Mal oder beliebig oft benutzt werden.
Der else-Teil mit Anweisungen kann 0 Mal oder 1 Mal verwendet werden.
Anstelle von a, b, oder c kann alles, was in 4. und
5. genannt wurde,
verwendet werden. Bei den Anweisungen muss mindestens ein Element aus 1.,
6. oder 8. verwendet werden.
Logisch betrachtet wird Folgendes gemacht:
- Wenn a wahr ist, dann werden anweisungen1 ausgeführt.
Der Rest wird ignoriert.
- Wenn a falsch ist und b ist richtig, dann werden anweisungen2 ausgeführt.
Der Rest wird ignoriert.
- Wenn a und b falsch sind und c ist richtig, dann werden anweisungen3 ausgeführt.
Der Rest wird ignoriert.
- ...
- Wenn alles davor falsch war, dann führe anweisungen4 durch.
6.3 for
So sieht eine for-Schleife aus:
for i in a .. b loop
-- hier anweisungenX
end loop;
Die Werte a und b können alles aus 3. sein. Bei den
Anweisungen muss mindestens ein Element aus 1.,
6. oder 8. verwendet werden.
Für den Namen der Variabel i gilt 7. Mit der for-Schleife wird
ein neuer "Block" aufgemacht. Existiert schon vorher eine Variabel mit dem gleichen
Namen, so wird diese von der neuen Variabel "überdeckt" und ist nicht mehr
"sichtbar".
Semantisch gesehen werden die anweisungenX (b - a + 1) Mal gemacht.
Ist die Differenz von b - a kleiner als 0, so werden die anweisungenX
gar nicht ausgeführt.
Die Variabel i erhält am Anfang den Wert von a und wird nach jedem
Schleifendurchlauf um 1 erhöht.
Verwenden Sie:
for i in reverse a .. b loop
-- hier anweisungenX
end loop;
so erhält die Variabel i am Anfang den Wert b und nach jeder
Schleifendurchlauf wird sie um 1 erniedrigt.
6.4 loop
So sieht eine loop-Schleife aus:
loop
--hier anweisungenY
end loop;
Bei den Anweisungen muss mindestens ein Element aus 1.,
6. oder 8. verwendet werden.
Semantisch gesehen werden die anweisungenY unendlich oft ausgeführt. Seien
Sie bitte vorsichtig, Sie können das Programm zum abstürzen bringen.
Wie Sie trotzdem bedingt/unbedingt abbrechen können, lesen Sie bitte
6.5. und 6.6.
6.5 while
So sieht eine while-Schleife aus:
while a loop
-- hier anweisungenZ
end loop;
Anstelle von a muss ein Element aus 4.
oder 5. stehen.
Falls a wahr ist, so werden anweisungenZ ausgeführt.
Danach wird auf dem Wahrheitswert von a wieder überprüft
und falls wahr, anweisungenZ wieder ausgeführt etc.
Falls der Wahrheitswert von a sich nicht nie ändert, so erreichen Sie
den gleichen Effekt mit der loop-Schleife. Falls a nicht mehr zutrifft,
so wird abgebrochen.
6.6 exit
exit; - Mit exit; springen Sie unbedingt oder falls
Sie eine if-Anweisung um Ihr exit; bauen bedingt aus einer for-, while-
oder loop-Schleife heraus.
Versuchen Sie bitte exit; so gut wie möglich zu vermeiden.
Das Verwenden von exit; gehört zum schlechten Programmierstil
und wird normalerweise im Programmierkurs I und II verboten.
exit; nicht innerhalb einer Schleife zu verwenden ist in Ada(Logo) falsch.
Wenn Sie z.B. eine doppelte Schleife benutzen und innerhalb der inneren Schleife exit;
benutzen, so wird nur die innere Schleife abgebrochen, die äußere wird jedoch
weiter ausgeführt. exit; springt immer bis zur nächsten Schleife, die
ihm umgibt.
7. Prozedur- und Variabel-Deklarationen
7.1. Variabel-Deklarationen
In AdaLogo gibt es (im Vergleich zu Ada nur) 2 Datentypen
integer und boolean. Variablen von Typ integer oder boolean
werden im Deklarationsblock definiert und können später verwendet werden.
Hier Beispiele für Variabel-Deklarationen:
- a : integer := -10; -- bsp1
- b : integer; -- bsp2
- c : boolean := true; -- bsp3
- d : boolean; -- bsp4
In Beispiel 1 und 2 werden integer (ganze Zahlen) definiert. a bekommt in Beispiel 1 sofort
den Wert -10 zugewiesen, während b keinen Wert bekommt. In Beispiel 3 und 4 werden
die Variablen c und d als boolean definiert. c hat sofort den Wert true,
d jedoch bleibt unbestimmt.
Vorsicht: falls später auf
die Variabel b und d zugegriffen werden, ohne dass b und d jemals einen konkreten Wert zugewiesen
bekommen, so haben die Variablen b und d wie in Ada einen zufälligen Wert -
das kann zu schweren Nebeneffekten
führen!
7.2. Prozedur-Deklarationen
Hier Beispiele, wie Prozeduren definiert werden:
-- bsp1:
procedure line is
-- Deklarationen hier
begin
pen_down;
forward(100);
turn(180);
forward(100);
turn(180);
end;
-- bsp2:
procedure quadrat (seitenlaenge : integer) is
-- Deklarationen hier
begin
pen_down;
for i in 1..4 loop
forward(seitenlaenge);
turn(90);
end loop;
end;
-- bsp3:
procedure schwarzeflaeche
(laenge : integer; breite : integer; do_it : boolean) is
-- Deklarationen hier
begin
if do_it then
for l in 1..breite/2 loop
forward(laenge);
turn(90);
forward(1);
turn(90);
forward(laenge);
turn(-90);
forward(1);
turn(-90);
end loop;
end if;
end;
In Beispiel 1 wird eine einfache Linie gezeichnet. Die Prozedur line erhält keine
Eingabe-Parameter. Die Prozedur Quadrat erhält als "in"-Parameter die Seitenlänge
und zeichnet ein Quadrat mit dieser Seitenlänge. Innerhalb dieser Prozedur ist
die Variabel seitenlaenge bekannt und sie wird dazu verwendet, um die Seitenlänge
des Quadrates zu zeichnen. An Beispiel 3 können Sie erkennen, dass es auch mehrere Eingabe-Parameter
sein können. Eingabe-Parameter können sowohl integer als auch boolean
sein.
Zwischen is und begin können weitere Deklarationen folgen.
Unter anderem bedeutet das, dass Sie weitere Unter- und Unterprozeduren beliebig verschachtelt
definieren können.
Variabel-Namen sind (wie in Ada) definiert:
- Der erste Buchstabe muss ein Buchstabe (a-z) oder ein _ sein.
- Die weiteren Buchstaben können Buchstaben (a-z), Zahlen (0-9) oder _ sein.
- Groß- und Kleinschreibung spielen keine Rolle.
- Vorsicht: dabei sind Sonderzeichen, Umlaute oder ß nicht erlaubt. Sie schreiben daher lieber
oe, ae, ue und ss.
- Reservierte Wörter dürfen nicht benutzt werden.
Die Sichtbarkeit der Variablen und Prozeduren ist wichtig.
Folgende Zeilen sind gültig:
a : integer := 10;
b : integer := a * a;
da
b a bereits sehen kann.
Folgende Zeilen sind
nicht gültig:
a : integer := b * b
b : integer := 10;
da
b für
a noch nicht sichtbar ist.
Die Sichtbarkeit von Prozeduren ist in AdaLogo anders als in Ada!
Folgende Zeilen ist in AdaLogo möglich, in Ada jedoch nicht!
procedure bla is begin
blubb;
end;
procedure blubb is begin
forward(100);
end;
8. Wertzuweisungen und Prozedurenaufrufe
8.1 Wertzuweisungen
Hier einpaar Beispiele:
a := 10; -- bsp1
b := random(10,25); -- bsp2
a := turtle_x; -- bsp3
c := true; -- bsp4
d := turtle_y < a; -- bsp5
Beispiele 1, 2 und 3 sind Wertzuweisungen von integer Variablen,
vorausgesetzt ist, dass diese Variablen a, b schon vorher im Deklarationsblock
definiert worden sind.
Beispiele 4 und 5 sind Wertzuweisungen von boolean, auch hier ist
die Voraussetzung, dass diese schon vorher als boolean deklariert
worden sind.
8.2 Prozedur-Aufrufe
Hier einpaar Beispiele:
line; -- bsp1
quadrat(4); -- bsp2
schwarzeflaeche(a,10,true); -- bsp3
Diese 3 Beispiele beziehen sich auf 7.2.
line; ist eine Prozedur ohne Eingabe-Parameter, quadrat hat einen Eingabeparameter
als integer, während schwarzeflaeche 3 Eingabe-Parameter hat, wobei
die ersten 2 Parameter integer sind, der 3. Parameter ist von Typ boolean.
Wurden die Prozeduren im Deklarationsbereich mit n Parametern (n ≥ 0) definiert, so
müssen sie beim Aufruf ebenfalls n Eingabe-Parameter bekommen, diese müssen vom
Typ mit der Definition übereinstimmen.
9. Rekursion
Folgende Zeilen sind ein Beispiel für Rekursion:
with adalogo;
use adalogo;
procedure foobar is
procedure viele_quadrate(kante : integer) is
begin
for i in 1..4 loop
forward(kante);
turn(90);
end loop;
if kante > 42 then
viele_quadrate(kante-5);
elsif kante < -84 then
null;
else
viele_quadrate(kante-5);
end if;
end;
begin
viele_quadrate(84);
viele_quadrate(42);
turn(90);
viele_quadrate(84);
viele_quadrate(42);
end;
Innerhalb der Prozedur
viele_quadrate ruft die Prozedur sich
selbst auf. Zu beachten ist, dass Sie für eine Abbruch-Bedingung
sorgen müssen, da ansonsten eine endlose Rekursion entsteht. Ein anderes
Beispiel für rekursives Aufrufen, finden Sie im Beispiel
hilbert.
Es ist auch möglich zwei oder mehr Prozeduren zu definieren, die sich
gegenseitig aufrufen. Entnehmen Sie aus der Informatik-Vorlesung, wann eine
Prozedur A eine Prozedur B aufrufen kann und wann nicht. Hierbei spielt die
Sichtbarkeit eine Rolle, die bei Unterprozeduren nicht immer gegeben sind.
Die Sichtbarkeit zu erklären würde den Rahmen dieser Seite sprengen.