
Pointer sind das mächtigste Werkzeug in C. Mit & bekommst du die Adresse, mit * greifst du auf den Wert zu – und eine Funktion kann damit Variablen des Aufrufers wirklich verändern!
Pointer – Grundkonzept
| Operator | Name | Bedeutung | Beispiel |
|---|---|---|---|
| & | Adressoperator | Adresse einer Variable | &x |
| * (Deklaration) | Pointer-Typ | Deklariert Pointer | int *p; |
| * (Zugriff) | Dereferenzierung | Wert an der Adresse | *p |
int x = 42; int *p = &x; // p zeigt auf x printf("%d\n", *p); // 42 *p = 100; // x ist jetzt 100! printf("%d\n", x); // 100
Call by Reference mit Pointern
Mit Pointern kann eine Funktion die Original-Variable ändern:void f(int *n) {{ *n = *n * 2; }}f(&x); → x wird verdoppelt
Visualisierung im Speicher
Ein Pointer ist selbst eine Variable, die eine Adresse als Wert speichert. Die folgende Tabelle zeigt wie Variablen und Pointer im Speicher aussehen (Adressen vereinfacht):
| Variable | Adresse | Wert |
|---|---|---|
int x = 42 | 0x7fff0001 | 42 |
int *p = &x | 0x7fff0002 | 0x7fff0001 (zeigt auf x) |
*p | — | 42 (Wert, auf den p zeigt) |
Adressen sind vereinfachte Beispiele
Echte Speicheradressen sehen aus wie 0x7ffee4b3c8a0. Die genaue Adresse hängt vom Betriebssystem und Laufzeitumgebung ab. Wichtig ist das Prinzip: p speichert die Adresse von x, *p liefert den Wert an dieser Adresse.
Pointer-Arithmetik
Bei Pointer-Arithmetik addiert C nicht einfach 1 Byte, sondern 1 × sizeof(Typ). Bei einem int* springt p+1 also um 4 Bytes weiter, bei einem char* um 1 Byte.
| Typ | p+1 bedeutet | Sprung in Bytes |
|---|---|---|
int *p | nächste int-Variable | +4 Bytes |
char *p | nächstes Zeichen | +1 Byte |
double *p | nächste double-Variable | +8 Bytes |
int arr[3] = {10, 20, 30}; int *p = arr; // p zeigt auf arr[0] printf("%d\n", *p); // 10 printf("%d\n", *(p+1)); // 20 (= arr[1]) printf("%d\n", *(p+2)); // 30 (= arr[2]) // arr[i] und *(arr+i) sind identisch!
NULL-Pointer
Ein Pointer sollte immer initialisiert werden. Wenn er noch auf nichts zeigt, verwendet man NULL als sicheren Anfangswert.
int *p = NULL; // sicherer Anfangswert if (p != NULL) { // immer prüfen vor Zugriff! printf("%d\n", *p); } else { printf("Pointer ist NULL!\n"); } // Zugriff auf NULL ohne Prüfung: // *p = 5; → Segmentation Fault (Absturz)!
| Situation | Verhalten |
|---|---|
int *p = NULL; | Sicher – p zeigt auf nichts, klar definiert |
if (p != NULL) | Pflicht vor jedem Zugriff via Pointer |
*p wenn p == NULL | Segmentation Fault – Programmabsturz |
Häufige Fehler
| Fehler | Problem | Lösung |
|---|---|---|
| int *p; *p = 5; | Uninitialisierter Pointer zeigt auf zufällige Adresse – undefiniertes Verhalten! | Immer initialisieren: int *p = NULL; oder int *p = &x; |
| & und * verwechseln | & = Adresse von, * = Wert an der Adresse | Merkhilfe: & = "Adresse-von", * = "Wert-an" |
| Dangling Pointer | Pointer nach free(p) weiter verwenden – zeigt auf freigegebenen Speicher | Nach free(p) sofort p = NULL; setzen |
⚠️ Uninitialisierte Pointer sind extrem gefährlich!
Ein Pointer ohne Initialisierung enthält eine zufällige Adresse aus dem Speicher. Ein Zugriff darauf kann Daten überschreiben, Abstürze verursachen oder – noch schlimmer – still falsche Ergebnisse liefern. Immer mit NULL oder einer gültigen Adresse initialisieren!
⚡ Code-Simulator
Teste den Code direkt im Browser – printf-Ausgaben werden simuliert:

Experimentiere mit dem Code – das ist der beste Weg um Pointer und structs wirklich zu verstehen!
🎯 Wissens-Quiz
📋 Spickzettel
✅ Checkliste Unit 26
- Ich kann einen Pointer deklarieren und initialisieren
- Ich kenne & (Adresse) und * (Dereferenzierung)
- Ich kann Call by Reference mit Pointern implementieren
- Ich weiß was ein NULL-Pointer ist