C-Zeiger meistern: Praktische Schritte zur fortgeschrittenen Programmierung
Zeiger in C sind leicht und spaßig zu lernen. Einige C-Programmieraufgaben lassen sich mit Zeigern einfacher lösen, und andere, wie dynamische Speicherverwaltung, können ohne Zeiger gar nicht durchgeführt werden. Es ist also notwendig, Zeiger zu lernen, um ein versierter C-Programmierer zu werden.
Wie Sie wissen, ist jede Variable eine Speicherstelle und jede Speicherstelle hat eine Adresse, die mit dem Adressoperator & abgerufen werden kann. Beispiel:
#include <stdio.h>
int main() {
int var1;
char var2[10];
printf("Adresse von var1: %p\n", (void*)&var1);
printf("Adresse von var2: %p\n", (void*)&var2);
return 0;
}
Ausgabe (Beispiel):
Adresse von var1: 0x7ffd8b3c
Adresse von var2: 0x7ffd8b36
Was sind Zeiger?
Ein Zeiger ist eine Variable, deren Wert die Adresse einer anderen Variable ist – also die direkte Adresse der Speicherstelle. Wie jede Variable oder Konstante müssen Sie einen Zeiger deklarieren, bevor Sie ihn verwenden, um eine Variablenadresse zu speichern. Die allgemeine Form:
typ *var-name;
typ ist der Basistyp des Zeigers (gültiger C-Datentyp), var-name der Name der Zeigervariablen. Der Stern * kennzeichnet die Variable als Zeiger. Gültige Deklarationen:
int *ip; // Zeiger auf int
double *dp; // Zeiger auf double
float *fp; // Zeiger auf float
char *ch; // Zeiger auf char
Der tatsächliche Datentyp des Werts aller Zeiger ist derselbe: eine lange hexadezimale Zahl, die eine Speicheradresse darstellt. Der einzige Unterschied zwischen Zeigern verschiedener Datentypen ist der Datentyp der Variable, auf die der Zeiger zeigt.
Wie man Zeiger verwendet
Wichtige Operationen mit Zeigern: (a) Zeigervariable definieren, (b) Adresse einer Variable dem Zeiger zuweisen, (c) Wert an der im Zeiger gespeicherten Adresse zugreifen. Dies geschieht mit dem unären Operator * (Dereferenzierung).
Beispiel
#include <stdio.h>
int main() {
int var = 20;
int *ip;
ip = &var; // Adresse von var in ip speichern
printf("Adresse von var: %p\n", (void*)&var);
printf("Adresse in ip: %p\n", (void*)ip);
printf("Wert von *ip: %d\n", *ip); // Dereferenzierung
return 0;
}
Ausgabe:
Adresse von var: 0x7ffd8b3c
Adresse in ip: 0x7ffd8b3c
Wert von *ip: 20
NULL-Zeiger
Es ist gute Praxis, einer Zeigervariablen NULL zuzuweisen, wenn keine genaue Adresse zugewiesen werden soll. Ein solcher Zeiger heißt Nullzeiger.
NULL ist eine Konstante mit Wert 0, definiert in mehreren Standardbibliotheken. Beispiel:
#include <stdio.h>
int main() {
int *ptr = NULL;
printf("Wert von ptr: %p\n", (void*)ptr);
return 0;
}
Ausgabe: Wert von ptr: (nil) (oder 0x0)
In den meisten Betriebssystemen dürfen Programme nicht auf Speicher an Adresse 0 zugreifen (reserviert vom OS). Adresse 0 signalisiert, dass der Zeiger nicht auf einen zugänglichen Speicherort zeigt. Konventionell bedeutet ein Nullwert, der Zeiger zeigt auf nichts.
Prüfung auf Nullzeiger:
if (ptr) // wahr, wenn ptr NICHT null
if (!ptr) // wahr, wenn ptr null
Zeiger im Detail
Zeiger haben viele, aber leicht verständliche Konzepte und sind sehr wichtig für C. Folgende Konzepte sollten klar sein:
| Nr. | Konzept & Beschreibung |
|---|---|
| 1 | Zeigerarithmetik – Vier arithmetische Operatoren: ++, --, +, - |
| 2 | Array von Zeigern – Arrays, die mehrere Zeiger halten. |
| 3 | Zeiger auf Zeiger – C erlaubt Zeiger auf Zeiger (und so weiter). |
| 4 | Zeiger an Funktionen übergeben – Call by Reference: Übergebener Wert kann in der aufrufenden Funktion geändert werden. |
| 5 | Zeiger aus Funktionen zurückgeben – Funktionen können Zeiger auf lokale/static/dynamische Variablen zurückgeben. |
Zeigerarithmetik Beispiel
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // zeigt auf erstes Element
printf("ptr: %p, *ptr: %d\n", (void*)ptr, *ptr);
ptr++; // nächstes Element (int = 4 Bytes)
printf("ptr: %p, *ptr: %d\n", (void*)ptr, *ptr);
ptr += 2;
printf("ptr: %p, *ptr: %d\n", (void*)ptr, *ptr);
return 0;
}
Zeiger auf Zeiger Beispiel
#include <stdio.h>
int main() {
int var = 3000;
int *ptr = &var;
int **pptr = &ptr;
printf("var: %d\n", var);
printf("*ptr: %d\n", *ptr);
printf("**pptr: %d\n", **pptr);
return 0;
}
C Sprache
- C Variablen, Konstanten und Literale: Ein vollständiger Leitfaden
- C Speicherklassen verstehen: Gültigkeitsbereich, Lebensdauer und Performance
- C-Zeiger meistern: Praxisnahes Experten-Tutorial
- Beziehung zwischen Arrays und Zeigern in C verstehen
- C-Programmierung: Adressen & Zeiger an Funktionen übergeben – Praxisleitfaden
- C-Structs und Zeiger meistern: Praxisleitfaden
- Pythons global-Schlüsselwort meistern: Wie & wann man es verwendet
- C++ Zeiger meistern: Konzepte, Beispiele & praktische Anwendungen
- C Variablen, Datentypen und Konstanten – Ein praktischer Leitfaden
- Zeiger in C: Umfassender Leitfaden zu Typen, Verwendung und Best Practices