1. Aufbau des Speichers
Jeder Computer hat Arbeitsspeicher. Was ist das eigentlich, welche Eigenschaften hat er und – am wichtigsten – was bringt uns das?
Jedes Programm (auch Programme, die in C# geschrieben sind) wird vor dem Ausführen in den Arbeitsspeicher geladen. Im RAM liegt der Programmcode (der vom Prozessor ausgeführt wird) und die Programmdaten (die das Programm selbst in den Speicher legt).
Was ist also Arbeitsspeicher und woran erinnert er?
Stell dir Excel vor 😎 Ein Excel-Blatt besteht aus Zellen, und jede Zelle hat ihre einzigartige Nummer (A1, A2, ... B1, B2). Wenn du die Nummer der Zelle kennst, kannst du immer einen Wert reinschreiben oder den gespeicherten Wert auslesen. Der Speicher eines Computers ist ähnlich aufgebaut.

Das Programm und seine Daten werden während der Ausführung im Speicher gehalten. Der gesamte Speicher des Computers besteht aus kleinen Zellen – Bytes. Jede Zelle hat ihre eigene Nummer – 0, 1, 2, 3, ...; (die Nummerierung startet bei null). Wenn wir die Nummer der Zelle kennen, können wir Daten dort speichern oder auslesen. In manchen Zellen liegt der Programmcode – eine Reihe von Befehlen für den Prozessor, in anderen – die Daten des Programms. Die Zellnummer nennt man auch Adresse der Zelle.
Der Prozessor kann Befehle aus dem in den Speicher geladenen Programm ausführen. Fast alle Prozessorbefehle laufen so ab: Daten aus bestimmten Zellen holen → etwas damit machen → Ergebnis in andere Zellen schreiben.
Wenn man hunderte solcher einfachen Befehle kombiniert, bekommt man komplexe und nützliche Befehle.
Wenn im Programmcode eine Variable deklariert wird, bekommt sie ein Stück noch nicht belegten Speicher. Meistens sind das ein paar Bytes. Beim Deklarieren einer Variablen muss man immer den Typ der Information angeben, die das Programm darin speichern wird: Zahlen, Text oder andere Daten. Ohne den Typ zu kennen, weiß man ja nicht, wie groß der Speicherblock für die Variable sein muss.
In den Anfängen der Computertechnik haben Programme einfach mit den Nummern der Speicherzellen gearbeitet, aber später hat man den Zellen zur Bequemlichkeit der Programmierer Namen gegeben. Der eindeutige Name einer Variablen ist vor allem für die Programmierer gedacht: Das Programm selbst käme auch nur mit Nummern klar.
2. Variablen im Speicher
In C# gibt es 4 grundlegende Datentypen für ganze Zahlen: byte, short, int und long.
| Typ | Größe, Byte | Namensherkunft |
|---|---|---|
| byte | 1 | Byte, weil er genau ein Byte Speicher belegt |
| short | 2 | Abkürzung für Short Integer |
| int | 4 | Abkürzung für Integer |
| long | 8 | Abkürzung für Long Integer |
Außerdem gibt es in C# zwei Gleitkommatypen – float und double:
| Typ | Größe, Byte | Namensherkunft |
|---|---|---|
| float | 4 | Abkürzung für Floating Point Number |
| double | 8 | Abkürzung für Double Float |
Jedes Mal, wenn das Programm eine Variable erstellt, wird dafür ein kleiner Speicherbereich reserviert (die Größe hängt vom Typ der Variablen ab).
int a = 10;
Die Adresse einer Variablen ist die Adresse der ersten Zelle des für sie reservierten Speicherblocks.
C#-Programmen ist es verboten, direkt auf den Speicher zuzugreifen. Die gesamte Speicherverwaltung läuft streng unter Kontrolle von C# und .NET.
3. Typ string im Speicher
Der Typ string kann große Datenmengen speichern, deshalb ist das nicht einfach nur ein Datentyp, sondern ein vollwertiges Objekt.
Die eigentlichen Daten vom Typ string (Text) werden in einem speziellen Objekt gespeichert, für das Speicher reserviert wird, und die Adresse dieses Objekts wird in der Variablen gespeichert, für die ebenfalls Speicher reserviert wird.

- Die Variable a vom Typ int belegt 4 Bytes und speichert den Wert 1.
- Die Variable b vom Typ int belegt 4 Bytes und speichert den Wert 10,555. Das Komma ist hier kein Dezimaltrennzeichen, sondern trennt die Stellen. Die Nachkommastelle wird durch einen Punkt getrennt.
- Die Variable d vom Typ double belegt 8 Bytes und speichert den Wert 13.001.
- Die Variable str vom Typ string belegt 4 Bytes und speichert den Wert D12 – die Adresse der ersten Zelle des Objekts, das den Text enthält.
Das Objekt vom Typ string (das den Text enthält) wird in einem eigenen Speicherblock gehalten. Die Adresse seiner ersten Zelle wird in der Variablen str gespeichert.
4. Was passiert beim Zuweisen
Noch eine wichtige Sache – wie funktioniert das Zuweisen. Zum Beispiel:
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
In diesem Beispiel werden im Speicher zwei Zellen angelegt: eine für a, eine für b. Wenn wir b = a; schreiben, wird der Wert kopiert (10), nicht die "Box" selbst. Änderungen an b haben keinen Einfluss auf a.
Jetzt das Gleiche, aber mit Strings:
string s1 = "Hallo";
string s2 = s1;
s2 = s2 + " Welt";
Console.WriteLine(s1); // "Hallo"
Console.WriteLine(s2); // "Hallo Welt"
Hier verweisen beide Variablen s1 und s2 auf denselben String "Hallo" bis zur Änderung. Aber wenn wir s2 = s2 + " Welt" machen, wird für s2 ein neuer String "Hallo Welt" erzeugt, während s1 weiterhin auf den alten String "Hallo" zeigt.
5. Warum wird in der Programmierung alles ab null nummeriert?
Viele Leute wundern sich, warum in der Programmierung fast überall ab null gezählt wird. Es gibt nämlich viele Situationen, in denen das Zählen ab null praktischer ist (auch wenn es manchmal praktischer ist, ab 1 zu zählen).
Das einfachste Beispiel ist die Speicheradressierung. Wenn deiner Variablen 4 Bytes Speicher zugewiesen werden und du hast X – die Adresse des ersten Bytes, wie lauten dann die Adressen aller Bytes? X+0, X+1, X+2, X+3. Schon hast du eine Gruppe von Bytes mit den Indizes 0, 1, 2, 3.
Wenn wir über relative Adressen innerhalb eines Datenblocks nachdenken, bekommen wir immer eine Nummerierung ab null. Das ist der erste und häufigste Grund, warum ab null gezählt wird.
GO TO FULL VERSION