 |
Übung 21.1 (4 Punkte)
Besorgen Sie sich eine funktionierende Klasse Stack und erstellen Sie dann eine Tochterklasse Stackmaschine, welche die vier Methoden add(), sub(), mul() und div() zur Verfügung stellt. Diese vier Methoden sollen genauso arbeiten, wie im Theorieteil Stackmaschinen beschrieben wurde. Außerdem benötigt Ihre Stackmaschine noch eine show()-Methode, damit Sie unabhängig vom Objektinspektor die Klasse testen können. Wenn die Mutterklasse Stack, die Sie sich besorgt haben, bereits eine funktionierende show()-Methode besitzt, müssen Sie hier nichts mehr programmieren.
Erstellen Sie dann eine konsolenorientierte Klasse Test (also kein Applet), die Ihre Stackmaschine testet. Diese Test-Klasse könnte z.B. folgenden Code enthalten:
maschine = new Stackmaschine();
maschine.push(4);
maschine.push(3.14);
maschine.add();
maschine.push(8);
maschine.push(2.71);
maschine.sub();
maschine.mul();
maschine.show();
|
Übung 21.2 (3 Punkte)
Berechnen Sie mit Hilfe Ihrer Stackmaschine das Ergebnis folgenden Ausdrucks:
(3 + 5.1) / (6.7 - 3.2/4.5)
Wandeln Sie Ihr Testprogramm dazu entsprechend um. Das korrekte Endergebnis lautet: 1.3525
Sollten Sie etwas anderes herausbekommen, so funktioniert (a) Ihre Klasse Stackmaschine nicht korrekt (wahrscheinlich ein Fehler bei sub() oder div() ), oder ihre Klasse Test enthält (b) falsche Befehle oder (c) korrekte Befehle in falscher Reihenfolge.
|
Übung 21.3 (3 Punkte)
Schreiben Sie den Stackmaschinen-Code zur Berechnung folgenden Ausdrucks auf:
((24 - 17) * (38 + 12) - 8) * (5 + 2)

|
Übung 21.4 (4 Punkte)
Übertragen Sie das Gelernte in eine neue Klasse Codebuffer. Diese Klasse soll neben dem Konstruktor folgende Methoden haben:
public void liesDatei(String dateiname) throws IOException
Diese Methode kann ähnlich aufgebaut sein wie die Methode laden(), die Sie im Lexikon-Eintrag "Textdateien einlesen" kennengelernt haben. Allerdings sollen die Zeilen nicht in die Konsole ausgegeben werden wie in laden(), sondern in einem String-Array zwischengespeichert werden, damit andere Methoden später auf jede einzelne Zeile zugreifen können. Sie müssen die Klasse Codebuffer also mit einem String-Array ausstatten.
Übung 21.5 (2 Punkte)
Die in den String-Array eingelesenen Zeilen sollen jetzt durch eine Methode
public void anzeigen()
in der Konsole angezeigt werden. Ein Testprogramm für die Klasse Codebuffer müssen Sie noch nicht schreiben, es reicht, wenn Sie durch Aufruf der Methoden liesDatei() und anzeigen() demonstrieren, dass liesDatei() funktioniert. Vergessen Sie nicht, eine entsprechende Textdatei mit Stackmaschinencode in ihrem Projektordner zu platzieren.

|
Übung 21.6 (3 Punkte)
Erstellen Sie jetzt die Klasse Stackinterpreter, die Objekte der Klassen Stackmaschine und Codebuffer haben. Der Interpreter sollte eine Methode liesDatei() haben, die den Codebuffer veranlasst, die Codedatei einzulesen und dann - zu Kontrollzwecken - in der Konsole anzuzeigen.
Ein Interpretieren der Codezeilen ist hier noch nicht vorgesehen.

|
Übung 21.7 (4 Punkte)
Erstellen Sie jetzt die Klasse Codebuffer zwei Methoden:
public int gibNaechstenBefehl()
public double gibArgument()
Die Methode gibNaechstenBefehl() analysiert die aktuelle Codezeile* und gibt eine int-Zahl zurück, und zwar
1 = push, 2 = add, 3 = sub, 4 = mul und 5 = div.
Wurde kein gültiger Befehl erkannt, so soll eine negative Zahl zurück geliefert werden, als Fehlermeldung quasi.
Die Methode gibArgument() liefert das Zahlenargument des push-Befehls zurück. Wird gibArgument() aufgerufen, wenn zum Beispiel ein add-Befehl erkannt wurde, so soll der Zahlenwert 0 zurück geliefert werden. Es ist aber Sache des Programmierers des Stackinterpreters, dafür zu sorgen, dass dieser Fall gar nicht eintreten kann. Vielmehr muss der Interpreter so implementiert werden, dass gibArgument() nur dann aufgerufen wird, wenn der push-Befehl erkannt wurde.
*Sie müssen Ihren Codebuffer um ein Attribut aktuell erweitern. Dieses Attribut speichert, welche der Befehlszeilen gerade die aktuelle Befehlszeile ist. Wurde gibNaechstenBefehl() aufgerufen, so muss aktuell inkrementiert werden, so dass beim nächsten Aufruf von gibNaechstenBefehl() tatsächlich der Befehl in der nächsten Codezeile analysiert wird.

|
Übung 21.8 (2 Punkte)
Verbessern Sie jetzt die Methode
public void interpretiereNaechstenBefehl()
der Klasse Stackinterpreter. Die Methode soll jetzt genau das tun, was ihr Name besagt, den jeweils nächsten Befehl des Codebuffers zu interpretieren. Mit dem Objektinspektor oder mit eigens dafür geschriebenen Ausgabe-Methoden sollten Sie die Funktionsweise dieser Methode überprüfen.

|
Übung 21.9 (2 Punkte)
Die letzte Übung dieser Seite ist nicht mehr sehr schwer.
Ergänzen Sie die Klasse Codebuffer um eine sondierende Methode gibAnzahlZeilen(), welche die Anzahl der eingelesenen Codezeilen zurückliefert, und schreiben Sie dann für die Klasse StackInterpreter eine Methode
public void interpretiere()
welche für jede Programmzeile der Datei die Methode interpretiereNaechstenBefehl() aufruft. Am Ende, also nach dem letzten Aufruf von interpretiereNaechstenBefehl(), soll das oberste Stack-Element angezeigt werden, in dem ja das Endergebnis der Berechnung gespeichert ist.

|
Übung 21.10 (3 Punkte)
Schreiben Sie für die Klasse Stack eine anzeigen()-Methode, die den Stack in einem Java-Applet korrekt und auch einigermaßen "schön" anzeigt. Die jeweils neuen Elemente sollen sich oben im Stack befinden, die alten Elemente unten. Der Stack soll nach oben wachsen können.
Falls nicht alle Stack-Elemente dargestellt werden können, weil die Höhe zu klein gewählt wurde, so sollen nur die oberen Stack-Elemente angezeigt werden. Es wäre auch gut, wenn das oberste Stack-Element besonders gekennzeichnet würde.
Ein möglicher Methodenkopf könnte so aussehen:
public void anzeigen(Graphics g, int x, int y, int breite, int hoehe)
Testen Sie die Methode mit einem einfachen Java-Applet. Überprüfen Sie auch, ob der Stack nach Ausführen mehrerer push()- und pop()-Operationen noch korrekt dargestellt wird.

|
Übung 21.11 (2 Punkte)
Schreiben Sie für die Klasse Codebuffer eine analoge anzeigen()-Methode. Allerdings soll der Inhalt des Codebuffers von oben nach unten dargestellt werden (siehe Abbildungen weiter unten). Wurde die Höhe des Rechtecks zu klein gewählt, so sollen die unteren Zeilen nicht mehr dargestellt werden. Testen Sie auch diese Methode mit Ihrem Java-Applet.

|
Übung 21.12 (1 Punkt)
Fassen Sie die Ergebnisse der beiden letzten Übungen zusammen und schreiben Sie für die Klasse Stackinterpreter eine anzeigen()-Methode, die ihrerseits die graphischen anzeigen()-Methoden der Klassen Stack bzw. deren Tochterklasse Stackmaschine sowie Codebuffer aufruft. Die Koordinaten und Maße des Stack- und Codebuffer-Fensters sollen in Stackinterpreter.anzeigen() festgelegt werden, zum Beispiel auf eine Breite von 100 und eine Höhe von 350 Pixeln.

|
Übung 21.13 (1 Punkt)
Wenn wir schon einmal dabei sind und sowohl den Codebuffer mit der jeweils aktuellen Quelltextzeile und den Stack in einem Applet anzeigen, dann können wir ja eigentlich auch noch einen Button namens "Step" in das Applet einbauen. Jedes Mal, wenn der Anwender auf den Button klickt, soll der nächste Befehl des Codebuffers ausgeführt werden. Wenn zum Beispiel die Zahl 17 gepusht wird, erscheint nach dem Buttonklick die Zahl 17 oben im Stackfenster. Im Codebufferfenster wandert die Markierung für die aktuelle Codezeile eine Position weiter nach unten.

|
|
|