Wird geladen...

Referenzen vs. Zeiger

Zentrale Unterschiede: Nullbarkeit, erneutes Binden, Indirektion und Speichersemanik.

In C++ gibt es zwei wichtige Konzepte beim Arbeiten mit Daten: Pointer (Zeiger) und Referenzen. Beide werden verwendet, um auf eine andere Variable zu “verweisen”; sie unterscheiden sich jedoch in ihrer Funktionsweise, im Speicherverhalten und in der Sicherheit. In diesem Artikel werden wir Pointer und Referenzen, ihre Unterschiede und Anwendungsbereiche mit Beispielen betrachten.


1. Was ist ein Pointer?

Ein Pointer ist eine spezielle Variable, die eine Speicheradresse speichert. Mit Pointern kann man indirekt auf den Wert einer anderen Variable zugreifen.


#include <iostream>
using namespace std;

int main() {
    int zahl = 10;
    int *ptr = &zahl; // die Adresse von 'zahl' wird dem Pointer zugewiesen

    cout << "Wert von zahl: " << zahl << endl;
    cout << "Wert von ptr (Adresse): " << ptr << endl;
    cout << "Wert, auf den ptr zeigt: " << *ptr << endl;

    *ptr = 20; // Wert über den Pointer geändert
    cout << "Neuer Wert von zahl: " << zahl << endl;

    return 0;
}

Hier greift *ptr (Dereferenzierung) auf den Wert der Variable zu, auf die der Pointer zeigt. Da Pointer direkt Speicheradressen manipulieren können, sind sie sehr mächtig – aber auch gefährlich, wenn sie falsch verwendet werden.


2. Was ist eine Referenz?

Eine Referenz ist ein “Alias” für eine andere Variable. Im Gegensatz zu einem Pointer speichert sie keine Adresse, sondern teilt direkt denselben Speicherbereich. Eine Referenz muss beim Deklarieren sofort an eine Variable gebunden werden.


#include <iostream>
using namespace std;

int main() {
    int x = 50;
    int &ref = x; // ref ist eine Referenz auf x

    cout << "x: " << x << ", ref: " << ref << endl;

    ref = 100; // Wert von x über die Referenz geändert
    cout << "Neuer Wert von x: " << x << endl;

    return 0;
}

In diesem Beispiel teilt ref tatsächlich denselben Speicherort wie x. Wenn einer geändert wird, ändert sich der andere automatisch.


3. Unterschiede zwischen Pointer und Referenzen

Die folgende Tabelle zeigt die wichtigsten Unterschiede:

EigenschaftPointerReferenz
Deklaration int *p = &x; int &r = x;
Speichert Adresse? Ja, speichert eine Speicheradresse Nein, direkt mit Variable verknüpft
Kann NULL sein? Ja, kann nullptr sein Nein, muss immer eine Variable referenzieren
Neu zuweisbar? Ja, kann auf eine andere Adresse zeigen Nein, einmal gebunden nicht änderbar
Dereferenzierung Mit *p zugänglich Direkt verwendbar
Speicherverwaltung Vom Programmierer gesteuert (new/delete) Automatisch verwaltet
Performance Indirekter Zugriff Direkter Zugriff (schneller)

4. Speicheransicht

So verhalten sich Pointer und Referenzen im Speicher:


int x = 10;
int *ptr = &x;
int &ref = x;

cout << "&x: " << &x << endl;
cout << "ptr: " << ptr << endl;
cout << "&ref: " << &ref << endl;

Beispielhafte Speicheranordnung:


Variable | Adresse   | Wert
x        | 0x61ff0c  | 10
ptr      | 0x61ff08  | 0x61ff0c
ref      | 0x61ff0c  | 10

Wie man sieht, nutzt ref denselben Speicher wie x, während ptr seine eigene Adresse hat und eine andere (die von x) speichert.


5. Pointer und Referenzen in Funktionen

Pointer und Referenzen können als Parameter übergeben werden, um externe Variablen zu verändern.

Mit Pointer


void Erhoehe(int *p) {
    (*p)++;
}

int main() {
    int zahl = 5;
    Erhoehe(&zahl);
    cout << zahl; // 6
}

Mit Referenz


void Erhoehe(int &r) {
    r++;
}

int main() {
    int zahl = 5;
    Erhoehe(zahl);
    cout << zahl; // 6
}

Beide Methoden liefern dasselbe Ergebnis, aber die Verwendung von Referenzen ist einfacher und sicherer.


6. const Referenzen

Wenn man verhindern möchte, dass eine Referenz den Wert ändert, kann man das Schlüsselwort const verwenden.


void Ausgabe(const string &text) {
    cout << text << endl;
}

int main() {
    string nachricht = "C++ ist großartig!";
    Ausgabe(nachricht);
}

const &-Referenzen ermöglichen es, große Objekte ohne Kopie sicher an Funktionen zu übergeben, was auch die Performance verbessert.


7. Kombination von Pointer und Referenzen

Manchmal werden Pointer und Referenzen gemeinsam verwendet. Zum Beispiel kann man eine Referenz auf einen Pointer erstellen.


#include <iostream>
using namespace std;

int main() {
    int x = 5;
    int *p = &x;
    int *&refAufPointer = p; // Referenz auf Pointer

    *refAufPointer = 10;
    cout << x << endl; // 10
}

Diese Struktur mag kompliziert erscheinen, ist aber besonders bei dynamischem Speicher und Funktionsparametern nützlich.


8. Beste Anwendungsfälle

In modernem C++ sollte man vorzugsweise Referenzen oder Smart Pointer (z. B. std::unique_ptr) anstelle von rohen Pointern verwenden.


9. TL;DR

  • Ein Pointer speichert eine Adresse; eine Referenz ist ein Alias für eine Variable.
  • Ein Pointer kann nullptr sein; eine Referenz nicht.
  • Ein Pointer kann neu zugewiesen werden; eine Referenz bleibt fest gebunden.
  • *p greift auf den Wert zu, auf den der Pointer zeigt; Referenzen werden direkt verwendet.
  • const &-Referenzen übergeben große Objekte sicher ohne Kopie.
  • Pointer → für Speicherverwaltung; Referenzen → für einfachen, sicheren Zugriff.
  • Alle Beispiele können in Visual Studio 2022 oder GCC 11+ ausgeführt werden.

Ähnliche Artikel