Variablen beim Programmieren?

3 Antworten

m hat am Ende den Wert 32

var a = 10;
var n = 100 - 8;
var m = 2 * a + 15 - 3;
a = 200 + 20;

Console.WriteLine(a);
Console.WriteLine(n);
Console.WriteLine(m);

Ausgabe:

220
92
32

https://rextester.com/IFVHZ46373


Palladin007  27.05.2020, 11:39

Ich hab zu viel Zeit, hier also das Ganze dekompiliert, was im Hintergrund passiert und wie er es tatsächlich Schritt für Schritt berechnet.
Nicht direkt erschrecken lassen, der erste Code-Block ist IL-Code (das wird aus C#), das erkläre ich noch genauer.

// var a = 10
IL_0001: ldc.i4.s 10
IL_0003: stloc.0 // a

// var n = 100 - 8
IL_0004: ldc.i4.s 92
IL_0006: stloc.1 // n

// var m = 2 * a + 15 - 3
IL_0007: ldc.i4.2
IL_0008: ldloc.0 // a
IL_0009: mul
IL_000a: ldc.i4.s 15
IL_000c: add
IL_000d: ldc.i4.3
IL_000e: sub
IL_000f: stloc.2 // m

// a = 200 + 20
IL_0010: ldc.i4 220
IL_0015: stloc.0 // a

Der Teil vor dem Doppelpunkt (z.B. IL_0010) hat keine direkte Bedeitung, das sind Sprungpunkte, die sind z.B. für Schleifen sehr wichtig. Entscheidend ist, was nach dem Doppelpunkt kommt, denn das sind die eigentlichen Befehle.
In den Komentaren hab ich den dazu passenden Code darüber geschrieben, bzw. beim Speichern in eine Variable, wie die Variable in C# hieß.

Wenn Du es dir selber Befehl für Befehl anschauen willst, hier die verwendeten Befehle:

ldc.i4   - lädt die nachstehende Int-Zahl
ldc.i4.s - lädt die nachstehende Int-Zahl (effizienter)
ldc.i4.2 - lädt eine 2
stloc.0  - speichert den letzten Wert in Variable 0 (hier a)
stloc.1  - speichert den letzten Wert in Variable 1 (hier n)
stloc.2  - speichert den letzten Wert in Variable 2 (hier m)
mul      - Multipliziert die letzten beiden Werte und lädt
           das Ergebnis
add      - Addiert die letzten beiden Werte und lädt das
           Ergebnis
sub      - Subtrahiert die letzten beiden Werte und lädt das
           Ergebnis

Dieses ständige Laden und irgendwelche letzten Zahlen klingt vermutlich etwas merkwürdig. Das liegt daran, dass das Programm im Hintergrund eine Art Stapel (heiß auch Stack) nutzt, worauf es Werte ablegen kann. Wenn eine Zahl geladen wird, wird sie also auf den Stack ganz oben drauf gelegt.
Das Programm muss immer alle Zahlen in der richtigen Reihenfolge laden. Der Befehl für die Berechnung nimmt sich dann vom Stack so viele Zahlen, wie er für die Berechnung braucht, rechnet damit und legt das Ergebnis wieder auf den Stack. Will man mit diesem Ergebnis weiter rechnen, muss also nur eine weitere Zahl geladen werden, die nächste Berechnung nimmt sich dann die beiden letzten Zahlen auf dem Stack.

Die ersten beiden Blöcke, wie auch der Letzte (also in C# Zeile 1, 2 und 4) sind ziemlich kurz, denn sie laden nur eine Zahl und speichern sie in eine Variable. Da hat der Compiler optimiert, denn einfache Berechnungen führt er einfach selber aus und schreibt nur noch das Ergebnis, dann muss das Programm das nicht mehr berechnen und spart Zet.
Die Variable m ist aber spannend, denn da ist die Variable a im Spiel, weshalb der Compiler nicht mehr einfach nur Zahlen zusammen rechnen kann.

Für Zeile 3 kommt also etwas mehr Code bei raus und den "übersetze" ich Mal ins Deutsche:

Lade die Zahl 2
Lade die Zahl in Variable a (hier die 10)
Multipliziere die beiden Zahlen und lade das Ergebnis
Lade die Zahl 15
Addiere die beiden letzten Zahlen und lade das Ergebnis
Lade die Zahl 3
Subtrahiere die beiden letzten Zahlen und lade das Ergebnis
Speichere die letzte Zahl in Variable m

Wenn man das jetzt mit dem Wissen über den Stack durch geht und Schritt für Schritt interpretiert, kann man es auf die folgenden mathematischen Rechenschritte zusammenfassen:

2 * 10 = 20
20 + 15 = 35
35 - 3 = 32

Zum Schluss wird nur noch das Ergebnis 32 in die Variable m gespeichert.

1

Das ganze wird von oben nach unten abgearbeitet und es gilt Punkt vor Strich.

Btw in C/C++ musst du das * schreiben also m=2*a+15-3

m=2*10+15-3;

m=32