Speicher als Byte-Reihe
Der Arbeitsspeicher ist eine lange Reihe von Speicherzellen. Jede Zelle fasst ein Byte und hat eine Nummer — ihre Adresse.
- Byte:8 Bit, kleinste Einheit mit eigener Adresse.
- Adresse:Nummer eines Bytes, meist hexadezimal geschrieben:
0x1000. - Hexadezimal:Ziffern 0–9 und a–f (a = 10 … f = 15);
0x10= 16,0x1000= 4096. - Variable:belegt je nach Typ mehrere Bytes direkt hintereinander; ihre Adresse ist die des ersten Bytes.
- sizeof:
sizeof(int)odersizeof xliefert die Größe in Byte — ausgeben mit%zu.
#include <stdio.h> int main(void) { printf("char: %zu Byte\n", sizeof(char)); printf("int: %zu Byte\n", sizeof(int)); printf("float: %zu Byte\n", sizeof(float)); printf("double: %zu Byte\n", sizeof(double)); return 0; }
$ gcc groesse.c -o groesse $ ./groesse char: 1 Byte int: 4 Byte float: 4 Byte double: 8 Byte
- Typisch:So sind die Größen auf üblichen PCs. Sie hängen von System und Compiler ab — nur
charhat immer 1 Byte. - Lücken:Der Compiler legt z. B. ein
intgern an eine durch 4 teilbare Adresse — davor bleiben Bytes frei.
Lege das Speicher-Lineal an: Ziehe die Marken 1 und 2 auf Byte-Grenzen oder tippe in den Streifen — die nähere Marke springt dorthin. Mit der Tastatur: Marke fokussieren, ←/→ ein Byte, ↑/↓ eine Zeile. Umschließen die Marken genau eine Variable, wird ihr sizeof aufgedeckt.
char c; int n; double d; int a[3];
| Variable | Adresse | gemessen | sizeof |
|---|
Halte fest: Der Abstand zweier Adressen ist die Anzahl der Bytes dazwischen: Endadresse − Startadresse. Für eine einzelne Variable ergibt das genau ihr sizeof; freie Bytes davor oder danach gehören nicht dazu.
Beispiel: Wie viele Bytes belegen n, d und a zusammen? Abstand = Endadresse − Startadresse.
Einerstelle: C − 4 = 12 − 4 = 8; Sechzehnerstelle: 1 − 0 = 1.
Probe: sizeof(n) + sizeof(d) + sizeof(a) = 4 + 8 + 12 = 24.
Größe und Abstand: Eine Variable belegt sizeof Bytes ab ihrer Adresse. Anzahl Bytes = Endadresse − Startadresse.
Adressen abfragen
Der Adressoperator & liefert die Adresse einer Variablen; printf gibt sie mit %p hexadezimal aus.
#include <stdio.h> int main(void) { int punkte = 17; double temp = 21.5; printf("punkte: Wert %d, Adresse %p\n", punkte, &punkte); printf("temp: Wert %.1f, Adresse %p\n", temp, &temp); return 0; }
$ ./adresse punkte: Wert 17, Adresse 0x7fffefbd853c temp: Wert 21.5, Adresse 0x7fffefbd8540 $ ./adresse punkte: Wert 17, Adresse 0x7fffaf1f3f1c temp: Wert 21.5, Adresse 0x7fffaf1f3f20
- &punkte:Adresse von
punkte— nicht ihr Wert. - %p:Platzhalter für Adressen, Ausgabe hexadezimal mit
0x. - Echte Adressen:sind viel größer als 0x1000 — ein PC hat Milliarden Bytes.
- Jeder Start:liefert andere Adressen: Das Betriebssystem verteilt den Speicher zufällig (Schutz vor Angriffen).
#include <stdio.h> int main(void) { int alter; printf("Wie alt bist du? "); scanf("%d", &alter); // & liefert die Adresse von alter printf("In 5 Jahren bist du %d.\n", alter + 5); return 0; }
$ ./einlesen Wie alt bist du? 14 In 5 Jahren bist du 19.
- scanf:liest eine Eingabe ein, Platzhalter wie bei
printf. - Warum &:
scanfmuss wissen, wohin es die Zahl schreiben soll — also braucht es die Adresse.
Adressen: &x liefert die Adresse von x, Ausgabe mit %p. Einlesen: scanf("%d", &x);.
Allgemeine Hinweise
Das & bei scanf
Ohne & warnt gcc -Wall: format '%d' expects argument of type 'int *' — das Programm stürzt beim Einlesen ab (Segmentation fault).
Größen nicht raten
Schreibe sizeof(int) statt 4: Auf manchen Mikrocontrollern hat ein int nur 2 Byte.
sizeof mit %zu
sizeof liefert eine vorzeichenlose Größe. Mit %d warnt gcc -Wall, mit %zu passt es.
