Zeiger (Pointers) in C++

In dieser Lektion werden Zeiger in C++ behandelt. Ziel ist, die direkte Adressierung von Speicher, Pointer-Arithmetik und Referenzen zu verstehen.

1. Was ist ein Zeiger?

Ein Zeiger ist eine Variable, die die Speicheradresse einer anderen Variablen speichert.
int a = 10;
int* p = &a; // p speichert die Adresse von a
std::cout << "Adresse von a: " << p << std::endl;
std::cout << "Wert von a über p: " << *p << std::endl;

2. Syntax von Zeigern

Ein Zeiger wird durch das Sternchen * deklariert. Das Ampersand & liefert die Adresse einer Variable.

3. Zugriff auf Werte über Zeiger

Mit *p kann auf den Wert der Variablen zugegriffen werden, auf die der Zeiger zeigt.
int a = 5;
int* ptr = &a;

std::cout << *ptr << std::endl; // Ausgabe: 5
*ptr = 20; 
std::cout << a << std::endl;    // Ausgabe: 20

4. Pointer-Arithmetik

Zeiger können inkrementiert oder dekrementiert werden, um auf benachbarte Speicheradressen zuzugreifen (besonders bei Arrays nützlich).
int arr[3] = {10, 20, 30};
int* p = arr;

std::cout << *p << std::endl;   // 10
p++;
std::cout << *p << std::endl;   // 20
p++;
std::cout << *p << std::endl;   // 30

5. Null-Zeiger und Sicherheitsaspekte

Ein Zeiger, der auf nichts zeigt, sollte nullptr sein.
int* p = nullptr;
if (p != nullptr) {
    std::cout << *p << std::endl;
} else {
    std::cout << "Zeiger zeigt auf nichts!" << std::endl;
}
Dereferenzierung von Null-Zeigern führt zu undefiniertem Verhalten (crash). Deshalb immer überprüfen.

6. Zeiger auf Zeiger

Ein Zeiger kann die Adresse eines anderen Zeigers speichern.
int a = 5;
int* p = &a;
int** pp = &p;

std::cout << **pp << std::endl; // Ausgabe: 5

7. Zeiger und Arrays

Arrays und Zeiger sind eng verbunden. Der Name eines Arrays ist ein Zeiger auf das erste Element.
int arr[3] = {1,2,3};
int* p = arr;       // arr <=> &arr[0]
for(int i=0;i<3;i++)
    std::cout << *(p+i) << " ";
std::cout << std::endl;

8. Referenzen vs. Zeiger

Eine Referenz ist ein Alias für eine Variable und wird mit & deklariert. Anders als Zeiger kann eine Referenz nicht null sein und muss bei Deklaration initialisiert werden.
int a = 10;
int& ref = a;
ref = 20;
std::cout << a << std::endl; // Ausgabe: 20
Referenzen sind oft sicherer und einfacher zu verwenden als rohe Zeiger.

9. Zusammenfassung