|
|
|||||||
Folge 23.1: while-Schleifen |
|||||||
Schritt 1 - Was ist eine while-Schleife?Eine while-Schleife besteht - unabhängig von der Progammiersprache - aus folgenden Komponenten:
Wurde das Schleifenende erreicht, so wird wieder zum Schleifenanfang "gesprungen". Dann wird die Schleifenbedingung erneut überprüft, und wenn sie erfüllt ist, wird wieder der Schleifenkörper ausgeführt etc. |
|||||||
Schritt 2 - Analyse einer while-SchleifeBetrachten wir folgende while-Schleife in einer programmiersprachen unabhängigen Darstellung:i = 1 s = 0 solange i < 100 start s = s + i i = i + 1 ende Offensichtlich soll hier die Summe der Zahlen von 1 bis 100 gebildet werden. Der Schleifenanfang besteht aus dem Wort "solange". In Pascal verwendet man das Wort "While" für den Schleifenanfang, wobei Groß- und Kleinschreibung keine Rolle spielen, wir dürfen also auch "WHILE" schreiben oder "while". In Java muss das Schlüsselwort "while" - alles kleingeschrieben - verwendet werden, um den Anfang einer while-Schleife zu kennzeichnen. Die Schleifenbedingung besteht in dem einfachen Vergleich i < 100. Wenn der Wert der Variable i kleiner ist als 100, so ist die Schleifenbedingung erfüllt. Der Schleifenkörper besteht aus den beiden Zuweisungen s = s + i und i = i + 1. Das Schleifenende besteht hier aus dem Schlüsselwort "ende". In Pascal verwendet man das Schlüsselwort "end", um das Ende einer while-Schleife zu kennzeichnen, in Java schreibt man eine schließende geschweifte Klammer }. |
|||||||
Schritt 3 - Umsetzung in StackmaschinencodeDie Befehle aus Schritt 2 können folgendermaßen in Stackmaschinencode übersetzt werden:push 1 assign i push 0 assign s whilestart varpush i push 100 lt varpush s varpush i add assign s varpush i push 1 add assign i whileend Wir wollen nun eingehend besprechen, wie der Stackinterpreter diese Zeilen abarbeitet. 1. SchleifenanfangDer Stackinterpreter holt sich ja immer den nächsten Befehl aus dem Codebuffer. Steht in einer Zeile z.B. der Stackmaschinenbefehl push 17 so weiß der Interpreter, dass er die Stackmaschine veranlassen muss, den push-Befehl auszuführen.: if (bef == 1) masch.push(buff.gibNumArgument()); Steht in einer Zeile dagegen add so ruft der Interpreter den add-Befehl der Stackmaschine auf: if (bef == 2) masch.add(); Sieht der Interpreter dagegen den Befehl whilestart so führt der Interpreter den Befehl aus: if (bef == 8) buff.merkeWhile(); Hierzu muss der Codebuffer eine Methode zur Verfügung stellen, die ungefährt folgendermaßen arbeitet: Die Nummer der Zeile, in der das Wort whilestart steht, wird in einem Attribut gespeichert, zum Beispiel zeileWhilestart. Anschließend wird der Stackcode solange durchsucht, bis die Zeile mit dem Wort whileend gefunden wurde. Die Nummer der Zeile, in der dieses Wort steht, wird in einem anderen Attribut gespeichert, zum Beispiel zeileWhileend.
Hier sehen Sie den Screenshot eines Applets, in dem der Codebuffer entsprechend erweitert wurde. Der Interpreter hat soeben den whilestart-Befehl erkannt, und als Nächstes soll der varpush i - Befehl abgearbeitet werden. Der Stack ist deswegen leer, weil ja nach jedem assign-Befehl das oberste Stack-Element entfernt wird.
In der Übung 23.4 sollen Sie den Stackinterpreter dazu bringen, dass er wieder an den Anfang der while-Schleife springt. Allerdings führt nicht der Interpreter die Hauptarbeit durch, sondern er delegiert die Arbeit an den Codebuffer, indem er den Codebuffer-Befehl starteWhile() aufruft. Dieser Befehl sorgt dafür, dass der Programmzähler (in meinen Beispielen habe ich ihn aktuell genannt) wieder auf den Anfang der while-Schleife gesetzt wird, strenggenommen auf die darauf folgende Zeile. |
|||||||
weiter mit Folge 23.2: Schleifenbedingung
|
|||||||
|
Diese HTML-Seite wurde erstellt von Ulrich Helmich am 23. Juli 2006. |
|||||||