In dieser Lektion werden wir das Fachkonzept der Variablen in der Programmierung behandeln und uns detaillierter mit (u. a. mathematischen) Ausdrücken, Operatoren und Funktionen beschäftigen, um Werte aus anderen Werten zu berechnen.
Bisher haben wir in unseren Programmen mit den von Scratch vorgegebenen Daten gearbeitet – im Wesentlichen die Attribute von Figuren und Bühne, sowie globale Werte wie Mauszeigerposition, Lautstärke, Wert der Stoppuhr oder Antwort auf die letzte Frage. Um diese Werte abzufragen, werden bestimmte Werteblöcke verwendet, und es gibt zum Teil bestimmte Anweisungsblöcke, um diese Werte zu verändern (z. B. “setze x auf …”).
In vielen Situationen ist es allerdings nötig, weitere Daten zu speichern, um mit Informationen zu arbeiten, sie sich während der Programmausführung ändern können – beispielsweise wenn Sie einen Punktezähler in ein Spiel einbauen möchten, die Anzahl der richtigen Antworten in einem Quiz mitgezählt werden soll, oder es eine einstellbare Geschwindigkeit für bewegte Objekte geben soll. Um beliebige Daten zu speichern und wieder abzurufen, werden in der Programmierung Variablen verwendet, deren Verwendungszweck wir selbst festlegen.
In Scratch können dazu neue, von uns benannte Werteblöcke definiert werden, sogenannte “Variablenblöcke”, in denen jeweils ein beliebiger Wert gespeichert werden kann. So lässt sich beispielweise ein neuer Werteblock namens “Punkte” erzeugen, dessen Wert mit einer bestimmten Anweisung (“setze Punkte auf …”) verändert werden kann. Dieser Werteblock lässt sich dann im Programm verwenden, um die aktuelle Punktezahl zu speichern, bei bestimmten Ereignissen zu erhöhen und auf der Bühne anzuzeigen.
Eine neue Variable muss zunächst definiert werden. Dazu wird in Scratch die Schaltfläche “Neue Variable” in der Block-Kategorie “Variablen” ausgewählt und ein eindeutiger Bezeichner für die neue Variable vergeben – am besten ein aussagekräftiger Name, der angibt, was die Variable im Programm bedeutet (zum Beispiel “Tempo” für die Bewegungsgeschwindigkeit von Objekten). Anschließend erscheint ein neuer Werteblock mit dem Namen der neuen Variablen in der Block-Bibliothek. Durch Ankreuzen des Kästchens links neben dem Werteblock kann der Wert, der momentan in der Variablen gespeichert ist, live auf der Bühne angezeigt werden (wie wir es auch bereits von anderen Werten und Objekt-Attributen kennen).
Initial enthält jede neue Variable in Scratch den Wert 0. Um einen anderen Wert in der Variablen zu speichern wird der Anweisungsblock “setze Variable auf …” verwendet. Wenn diese Anweisung ausgeführt wird, speichert Sie den Wert, der für den Parameter angegeben wird, in der ausgewählten Variablen und überschreibt dabei den momentan vorhandenen Wert. Diese Anweisung wird als “Wertezuweisung” oder kurz Zuweisung bezeichnet. Das folgende Beispiel setzt den Wert der Variablen “Tempo” auf 25:
Um einen Wert zum aktuellen Wert der Variablen hinzuzuaddieren, kann auch die Anweisung “ändere Variable um …” verwendet werden (“inkrementelle Zuweisung”). Das folgende Beispiel zieht 5 vom aktuellen Wert der Variablen “Tempo” ab:
Als Parameter für die Zuweisung kann auch ein beliebiger Werteblock eingefügt werden (wie schon von anderen Anweisungen bekannt). In diesem Fall wird beim Ausführen der Zuweisung zunächst der momentane Wert dieses Werteblocks abgefragt und dieser Wert anschließend in die Variable geschrieben. So können auch Berechnungsergebnisse in einer Variablen gespeichert werden, hier beispielsweise die aktuelle x-Koordinate des Mauszeigers dividiert durch 10:
Der Variablenblock kann genau wie jeder andere Werteblock als Parameter in anderen Anweisungen verwendet werden. Wird die Anweisung ausgeführt, wird der momentan im Variablenblock gespeicherte Wert abgefragt. Hier wird beispielsweise der aktuellen Tempo-Wert zur x-Koordinate eines Objekts hinzuaddiert (links):
Genauso kann der Variablenblock auch als Operand in Operator-Werteblöcken verwendet werden, z. B. um zu prüfen, ob der aktuell gespeicherte Wert > 0 ist:
Bisher hatten wir Zustandswerte kennengelernt, die zu einzelnen Objekten gehören (die Attribute der Objekte, z. B. Position, Größe oder Kostümnummer) oder global sind, d. h. sich auf den gesamten Programmzustand beziehen (z. B. Position des Mauszeigers oder zuletzt eingegebene Antwort).
Variablen können ebenfalls als Objektvariablen oder globale Variablen definiert werden.
Globale Variable Tempo | Objektvariablen Tempo von zwei verschiedenen Objekten |
Beim Erzeugen eines neuen Werteblocks über die Schaltfläche “Neue Variable” erscheint ein Dialog, in dem ausgewählt werden kann, ob eine globale Variable (“Für alle Figuren”) oder eine Objektvariable für die aktuell ausgewählte Figur (“Nur für diese Figur”) erzeugt werden soll:
Soll es nur einen Tempowert geben, die durch alle Objekte im Programm gemeinsam genutzt wird, sollte diese Variable global definiert werden. Wenn verschiedene Objekte dagegen eigene Tempowerte haben sollen, die unabhängig voneinander unterschiedlich sein können, sollte die Variable in jedem dieser Objekte privat definiert werden.
Zu beachten ist noch, dass zum Abfragen einer Objektvariablen im Skript eines fremden Objekts nicht der Variablenblock verwendet wird (private Variablenblöcke erscheinen nur in der Block-Bibliothek, wenn “ihr” Objekt ausgewählt ist), sondern der Werteblock “Attribut von Objekt” aus der Kategorie “Fühlen” – z. B. für eine Objektvariable “Tempo” des Objekts “Rennwagen”:
Um zu entscheiden, ob eine Variable global oder privat definiert werden soll, sollte also überlegt werden, ob die Variable nur innerhalb von Skripten eines bestimmten Objekts verwendet wird, oder ob sie von mehreren Objekten gemeinsam oder unabhängig von Objekten genutzt wird. Variablen, die nur innerhalb eines Objekts genutzt werden, sollten privat sein, damit sie nicht mit anderen Variablen verwechselt oder fälschlicherweise von anderen Objekten verändert werden. Dieses Konzept wird in der Programmierung als Datenkapselung bezeichnet.
Als praktisches Beispiel zur Verwendung von Variablen dient hier ein kleines Point & Click-Spiel in Scratch. Laden Sie das Projekt Fische_Fangen.sb3 hier herunter: Download
In diesem Spiel bewegt sich ein Fisch zufällig durch ein Aquarium und kann durch einen Mausklick gefangen werden. In diesem Fall verschwindet er und taucht dann eine Sekunde später an einer anderen Position wieder auf. Das Spiel soll nun durch Variablen folgendermaßen erweitert werden:
Es soll ein Punktezähler hinzugefügt werden. Jeder erfolgreiche Klick auf den Fisch soll mit einem Punkt belohnt werden. Der aktuelle Punktestand soll auf der Bühne angezeigt werden.
Dazu definieren wir zunächst eine neue Variable namens “Punkte”. Diese Variable kann als globale Variable angelegt werden (beim Anlegen der neuen Variablen “Für alle Figuren” wählen), da sie unabhängig von einem bestimmten Objekt ist.
Anschließend fügen wir die Anweisung “ändere Punkte um 1” zum Skript für das Ereignis “Wenn diese Figur angeklickt wird” hinzu, so dass bei jedem Mausklick auf den Fisch der Wert der Variablen “Punkte” um 1 hochgezählt wird:
Damit wir den Punktestand während des Spiels sehen, muss das Kästchen links von der Variablen in der Block-Bibliothek angekreuzt werden:
Der Punktestand soll zu Beginn jedes Spiels auf 0 zurückgesetzt werden. Dieses Skript wird am besten zur Bühne hinzugefügt, da es einmal beim Programmstart ausgeführt werden soll und sich nicht auf bestimmte Objekte bezieht, sondern nur auf globale Werte (für solche Skripte ist die Bühne der beste Ort, da sie ebenfalls “global” ist):
Der Fisch soll höchstens dreimal gefangen werden können. Beim dritten Klick auf den Fisch soll er verschwinden und anschließend nicht wieder auftauchen.
Wenn der Fisch angeklickt wird und danach nur noch einen Treffer übrig hat, soll er außerdem rot eingefärbt werden. Dazu kann der Block “setze Effekt Farbe auf -25” verwendet werden:
Um die Anzahl der bisherigen Treffer zu zählen, legen wir ein neue Variable namens “meine Treffer” an. Da diese Variable unmittelbar zum Objekt “Fisch1” gehört, definieren wir sie als Objektvariable (beim Anlegen der Variablen “Nur für diese Figur” auswählen). Sie stellt quasi ein neues Attribut des Objekts dar.
Außerdem ergänzen wir das Skript so, dass:
Um zu verhindern, dass das Objekt nach seinem letzten Verschwinden unnötigerweise unsichtbar weiter über die Bühne gleitet, wird die Endloswiederholung durch eine bedingte Wiederholung ersetzt, die endet, wenn der Trefferwert des Objekts 0 erreicht.
Nun möchten wir noch, dass mehrere Fische im Spiel vorhanden sind, die sich unabhängig voneinander bewegen. Das lässt sich einfach dadurch erreichen, dass das Objekt “Fisch1” in der Objektliste durch einen Rechtsklick dupliziert wird. Da die Variable “meine Treffer” als Objektvariable definiert wurde, hat jeder Fisch nun seine eigene Trefferanzahl. Hätten wir die Variable global definiert, würden sich alle Fische fälschlicherweise eine gemeinsame Trefferanzahl teilen.
Im allgemeinsten Sinne ist eine Variable in der Programmierung ein benannter Wertespeicher, der jeweils einen Wert zur Zeit speichern kann. Im Programmverlauf lässt sich lesend auf den Wert zugreifen oder der Wert überschreiben. Die Anweisung, um einen Wert in einer Variablen zu speichern, wird als Zuweisung bezeichnet. Der Wert einer Variablen kann beliebig oft durch Zuweisungen überschrieben werden (der Wert ist also “variabel”, daher auch die Bezeichnung).
Bildlich lassen sich Variablen anhand des “Tafel-Modells” (auch “Whiteboard-Modell”) gut veranschaulichen. Hier wird jede Variable durch eine kleine Tafel mit einem eindeutigen Namen repräsentiert, auf welcher der aktuelle Wert geschrieben steht. Initial steht auf jeder solchen Tafel hier der Wert 0. Bei jeder Zuweisung wird der aktuelle Wert auf der Tafel ausgewischt und durch den neuen Wert überschrieben.
Zustand der Variablen x zu Beginn | Ausführen der Zuweisung “setze x auf 42” | Ausführen der Zuweisung “setze x auf x / 2” |
Bei der letzten Zuweisung wird zuerst der momentan vorhandene Wert von x gelesen, um die Division x / 2 zu berechnen, und anschließend der vorhandene Wert durch das Divisionsergebnis überschrieben.
Diese Analogie erklärt auch anschaulich, was passiert, wenn einer Variablen der Wert einer anderen Variable zugewiesen wird: Hier wird einfach der Inhalt der anderen Tafel abgeschrieben.
Variablen x, y zu Beginn | Zuweisung “setze x auf 42” | Zuweisung “setze y auf x” | Zuweisung “setze x auf x / 2” |
Die letzte Zuweisung ändert hier also nur den Wert von x, nicht den Wert von y.
Andere Metaphern eignen sich nur bedingt, da sie anfällig dafür sind, bestimmte Fehlvorstellungen von Variablen zu entwickeln. Verbreitet sind neben dem “Tafel-Modell” etwa das “Behälter-Modell” (auch “Schubladen-Modell” oder “Schachtel-Modell”) oder die Analogie zu Variablen in der Mathematik.2
Die Vorstellung einer Variable als Kiste oder Schublade, die einen Zettel mit dem gespeicherten Wert enthält, kann zu der Fehlvorstellung führen, dass eine Variable eine Liste bzw. Historie aller jemals in ihr gespeicherten Werte enthält. Tatsächlich enthält eine Variable zu jedem Zeitpunkt nur einen Wert.
Durch das Gleichsetzen von Variablen in der Programmierung und Variablen in mathematischen Gleichungen kann die Fehlvorstellung entstehen, dass Variablen durch Zuweisungen wie y = x + 1 logisch miteinander verknüpft werden – also eine spätere Änderung des Wertes der Variablen x gleichzeitig den Wert der Variablen y ändert.
Ein weiterer beliebter Fehler besteht darin, dass Bezeichner und Wert einer Variablen verwechselt werden, dass also beispielsweise angenommen wird, der Vergleich einer Variablen namens x mit dem Buchstaben “x” muss zwangsläufig wahr ergeben, auch wenn die Variable einen ganz anderen Wert enthält (siehe auch unten unter Zeichenkettenausdrücke). Tatsächlich zählt aber bei Vergleichen oder Berechnungen mit Variablen nur deren aktueller Inhalt, der klar von ihrem Namen unterschieden werden muss.
Als Ausdruck wird in der Programmierung ein Konstrukt bezeichnet, das sich zu einem Wert auswerten lässt – in Scratch repräsentiert durch Werteblöcke – also beispielsweise mathematische oder logische Ausdrücke.
Ohne Variablen hatten wir Ausdrücke bisher nur zum Ermitteln von Parameterwerten für Anweisungen oder Vergleiche verwendet. Mit Variablen können Berechnungsergebnisse nun gespeichert und an späterer Stelle oder in einem anderen Skript wiederverwendet werden, wodurch komplexere Berechnungen möglich sind. Die folgende Anweisung berechnet zum Beispiel den Radius eines Kreises aus der zuvor eingegebenen Kreisfläche entsprechend der Formel \(r = \sqrt{\frac{A}{\pi}}\) und speichert das Ergebnis in der Variablen “Radius”:
Variablen können – wie oben gesehen haben – beliebige Werte speichern und sogar verschiedene Arten von Werten, beispielsweise Zahlen oder Texte. Die Arten von Werten werden als Datentypen bezeichnet. Üblicherweise wird eine Variable im Programm nur zum Speichern von Werten eines bestimmten Datentyps verwendet, die von ihrem Verwendungszweck abhängt (z. B. ganze Zahlen für eine Variable, die einen Punktestand darstellt oder die Anzahl richtiger Antworten zählt). Das ist aber nur eine Konvention – Variablen sind in Scratch aber nicht per se festgelegt auf einen bestimmten Datentyp.
Die Ergebnisse von Berechnungen hängen zum einen vom Operator (z. B. Divisionsoperator /) und zum anderen von den Werten der Operanden ab. Ob und wie ein Operator auf seine Operanden angewendet werden kann, hängt dabei auch von den Datentypen der Operanden ab, also welche Art von Wert sie haben. Beispielsweise macht es keinen Sinn, den Divisionsoperator / auf eine Zahl und einen Text anzuwenden. Das gilt auch für Parameterwerte von Anweisungen und Kontrollstrukturen: Die Kontrollstruktur “wiederhole … mal” erwartet beispielsweise eine Ganzzahl, die Anweisung “gehe … Schritt” eine Zahl.
Scratch unterscheidet die folgenden drei Datentypen für Werte:
In Scratch stehen die gängigsten mathematischen Operatoren und Funktionen in der Kategorie “Operatoren” (grün) zur Verfügung:
Wenn diese Blöcke abgefragt werden, geben Sie das Berechnungsergebnis für die beiden enthaltenen Werte an (Addition, Subtraktion, Multiplikation oder Division). | |
Wird dieser Block abgefragt, gibt er den Teilungsrest der ganzzahligen Division von a durch b an, wobei a und b die beiden enthaltenen Werte sind. | |
Wird dieser Block abgefragt, gibt er den enthaltenen Wert gerundet auf die nächste Ganzzahl an. | |
Wird dieser Block abgefragt, gibt er das Berechnungsergebnis für den enthaltenen Wert an, wobei verschiedene Funktionen ausgewählt werden können (über das Symbol ▾), u. a.: Betrag, ab-/aufrunden, Wurzel, Sinus, Kosinus, Tangens, Logarithmus und Exponentialfunktion. | |
Wird dieser Block abgefragt, gibt er eine zufällig ausgewählte Zahl zwischen a und b an, wobei a und b die beiden enthaltenen Zahlen sind. Wenn a und b beide Ganzzahlen sind, wird eine Ganzzahl ausgewählt, sonst eine Dezimalzahl. |
Die mathematischen Operatoren haben alle einen Zahlenwert als Ergebnis und erwarten generell Zahlenwerte als Operanden. Wird stattdessen eine Zeichenkette als Parameterwert verwendet, die nicht als Zahlenwert interpretiert werden kann, wird sie wie der Zahlenwert 0 behandelt, wie das folgende Beispiel zeigt:
Für Zeichenketten gibt es eigene Werteblöcke in der Kategorie “Operatoren”, etwa um mehrere Zeichenketten verbinden oder um bestimmte Eigenschaften von Zeichenketten zu überprüfen:
Wird dieser Block abgefragt, gibt er die Aneinanderhängung (Konkatenation) der beiden enthaltenen Zeichenketten-Werte an. Für “Apfel” und “Banane” wird beispielsweise die Zeichenkette “ApfelBanane” als Wert zurückgegeben. | |
Wird dieser Block abgefragt, gibt er das n-te Zeichen der angegebenen Zeichenkette an, wobei n die im linken Feld angegebene Zahl ist. Für die Werte 1 und “Apfel” wird beispielsweise das Zeichen “A” zurückgegeben. | |
Wird dieser Block abgefragt, gibt er die Länge der angegebenen Zeichenkette an, also die Anzahl ihrer Zeichen. Für “Apfel” wird beispielsweise der Zahlenwert 5 zurückgegeben. | |
Wird dieser Block abgefragt, gibt er als Wahrheitswert an, ob die links angegebene Zeichenkette die rechts angegebene Zeichenkette enthält. Groß- und Kleinschreibung spielt dabei keine Rolle. Für “Apfel” und “a” wird also wahr zurückgegeben, für “Apfel” und “PF” ebenfalls. Dabei muss die Reihenfolge der Operanden berücksichtigt werden – für links “fel” und rechts “Apfel” wird beispielsweise falsch zurückgegeben, andersherum dagegen wahr. |
Als Operanden können hier natürlich auch andere Werteblöcke und Variablenblöcke verwendet werden. Die Auswertung macht allerdings nur Sinn, wenn die Blöcke Werte der erwarteten Datentypen zurückgeben. Das folgende Beispiel speichert zunächst die Eingaben auf zwei “frage”-Anweisungen in den beiden Variablen namens “Nadel” und “Heuhaufen” und wertet dann die Bedingung aus, ob der Wert der einen Zeichenfolge in der anderen enthalten ist:
In diesem Beispiel liegt es nahe zu denken, dass die Bedingung niemals erfüllt sein kann, da die Zeichenkette “Nadel” ja nicht in der Zeichenkette “Heuhaufen” enthalten ist. Aber Achtung: Das sind die Namen der Variablen und nicht ihre Werte! Die Werte der Variablen sind hier die beiden Texte, die wir jeweils als Antwort auf die beiden “frage”-Anweisungen eingeben. Geben wir zum Beispiel bei der ersten Frage “Speisekammer” und bei der zweiten “Eis” ein, so wird in der Variablen namens “Heuhaufen” der Wert “Speisekammer” und in der Variablen namens “Nadel” der Wert “Eis” gespeichert, so dass die Bedingung “[Wert der Variablen] Heuhaufen enthält [Wert der Variablen] Nadel” zu wahr ausgewertet wird.
Wird ein Zahlenwert für einen Parameter verwendet, für den eine Zeichenkette erwartet wird, so wird er intuitiv als Zeichenkette interpretiert, wie das folgende Beispiel zeigt:
In Lektion 2 haben wir bereits logische Ausdrücke kennengelernt, die als Bedingungen für die bedingte Wiederholung und Fallunterscheidung verwenden werden. Neben den Wahrheitswerteblöcken können mit Hilfe der logischen Operatoren auch logische Ausdrücke aus anderen Werten zusammengesetzt werden, etwa durch die Vergleichsoperatoren:
und die logischen Verknüpfungsoperatoren:
Die Operanden für die Vergleichsoperatoren können sowohl Zahlen als auch Zeichenketten sein. Der Datentyp der beiden Operanden sollte aber gleich sein. Die logischen Verknüpfungen erwarten dagegen Wahrheitswerte als Operanden. Das Ergebnis aller logischen Ausdrücke ist immer ein Wahrheitswert.
Obwohl Variablen prinzipiell für beliebige Zwecke verwendet werden können, gibt es in der Praxis eine Reihe typischer Anwendungsfälle für Variablen, die wir teils hier bereits kennengelernt haben und teils in den praktischen Übungen vertiefen werden. Solche typischen Anwendungsfälle sind unter anderem:
Das folgende Beispiel für eine Zählvariable zählt in der Variablen “Anzahl Mausklicks”, wie oft ein Objekt nach dem Programmstart angeklickt wird:
Das folgende Beispiel demonstriert eine Akkumulatorvariable “Summe Noten”. Hier wird die Summe von 10 Noten berechnet, um die Durchschnittsnote zu ermitteln:
Auch für Parameterwerte, die sich im Programmablauf selbst nicht ändern (also konstante Werte), kann es sich anbieten, den Wert in einer Variablen zu speichern, statt ihn direkt in die Anweisungen zu schreiben. So können Sie den Wert später schnell ändern, wenn sich herausstellt, dass er zu klein oder zu groß gewählt wurde. Anderenfalls müssten Sie den Wert manuell an jeder Stelle im Programm anpassen, an der er verwendet wird, was aufwendig und fehleranfällig ist.
Zum Beispiel: Alle Objekte im Spiel sollen mit 8 Bildern pro Sekunde animiert werden. Also hat jedes Objekt ein Skript der Form:
Stellen wir nun später fest, dass die Animationen zu langsam wirken, müssten wir den Parameterwert von “warte” in allen Skripten anpassen. Es ist also hilfreich, die Bildrate in einer globalen Variable zu speichern und deren Wert in allen Animationsskripten zu verwenden, statt einem festen Wert:
Die Variable können wir manuell mit dem Wert 8 belegen, indem wir den entsprechenden Block in der Block-Bibliothek anklicken, oder ihn zu Beginn des Startskripts der Bühne ausführen lassen:
Um die Bildrate aller Animationen im Programm nun nachträglich zu verändern, reicht es, einmal den Wert der Variablen “Bildrate” anzupassen.
Um den Ablauf von Programmen oder Programmabschnitten, deren Verhalten von ihren Variablenbelegungen abhängt, besser nachvollziehen zu können und gegebenenfalls Fehler in der Programmierung zu finden, kann es hilfreich sein, die Wertebelegungen der Variablen über die Zeit zu protokollieren. Ein einfaches Werkzeug dafür stellen die sogenannten Trace-Tabellen dar.
Eine Trace-Tabelle (auch: Ablaufverfolgungstabelle) protokolliert die Änderungen von Variablenwerten während des Programmablaufs in tabellarischer Form. Jede Spalte stellt dabei eine Variable dar, deren Zustand beobachtet werden soll. Die Zeilen stellen diejenigen Anweisungen dar, durch die sich ein beobachteter Wert ändert – bei Variablen also also Variablenzuweisungen. Die Anweisungen werden dabei in der Tabelle zeilweise in genau der Reihenfolge dargestellt, in der sie während der Programmausführung abgearbeitet werden.
Neben Variablen lassen sich auch andere Werteblöcke (z. B. Attribute von Objekten, der Wert des “Antwort-Blocks) in der Tracetabelle beobachten, wenn sie für den Programmablauf relevant sind und sich ihre Werte während des Ablaufs ändern.
Der folgende Abschnitt eines Scratch-Skripts (links) berechnet die Summe von mehreren Noten, die nacheinander eingegeben werden, in der Variablen “Summe Noten”. Die Anzahl der Noten wird zu Beginn eingegeben und am Ende die Durchschnittsnote angezeigt. Um den Ablauf besser nachzuverfolgen, nummerieren wir hier die Zuweisungen und “frage”-Anweisungen von oben nach unten durch und listen die Nummer der Anweisung, auf die sich die Zeile bezieht, in der Trace-Tabelle mit auf (rechts).
Testhalber vollziehen wir den Ablauf hier für die folgende Sequenz von Eingaben bei den “frage”-Anweisungen nach: 4, 2, 1, 3, 3. Hier sollte also der Mittelwert der vier Noten 2, 1, 3 und 3 berechnet werden. Anhand der Trace-Tabelle lässt sich nachvollziehen, dass hier am Ende das Ergebnis von 9 / 4, also korrekterweise der Wert 2.25 angezeigt wird.
Hinweise zur Darstellung der Trace-Tabelle: Vor der ersten Zuweisung im beobachteten Programmabschnitt ist der momentane Wert der Variablen unbekannt (analog der Wert des “Antwort”-Blocks vor der ersten “frage”-Anweisung). Der Eintrag ? in der Trace-Tabelle kennzeichnet einen unbekannten Wert. Die hellgrün hinterlegten Felder kennzeichnen, dass ein Wert zugewiesen wird und den vorigen Wert überschreibt.
Die Begriffe “lokale Variable” und “private Variable” haben in der objektorientierten Programmierung üblicherweise eine andere Bedeutung, weswegen hier vorrangig der formal richtige Begriff “Objektvariable” verwendet wird. ↩︎
siehe Peer Stechert: Fehlvorstellungen und Modelle bei Variablen aus der Reihe Informatikdidaktik kurz gefasst (Teil 15), Video bei YouTube ↩︎