Einleitung
Bevor ich auf das Thema “call by reference” eingehe, werde ich dir erklären was mit “call by value” gemeint ist. Am Ende gebe ich dir dann noch ein Beispiel wie du das selbe Ergebnis mit Pointern erreichen kannst und was die wesentlichen Unterschiede zwischen Pointern und Referenzen sind.
Voraussetzungen
- du solltest wissen was ein Bezeichner/eine Variable ist.
- du solltest wissen was Pointer sind.
- Begriffe wie Deklaration, zuweisen/initialisieren, Parameter, Argument sind dir bekannt.
Call by value
Im wesentlichen gibt es in der Programmierung zwei Möglichkeiten eine Variable aufzurufen:
- Call by value
- Call by reference
Call by value ist dir warscheinlich längst bekannt. Dabei handelt es sich um eine Übergabe des Wertes einer Variablen als Kopie, welches dem Parameter als Wert zugewiesen wird.
#include<iostream>
using namespace std;
void printX(int p);
int main(){
int x = 1; // Variable wird mit 1 initialisiert
printX(x); // Funktionsaufruf, x wird als Argument übergeben.
cout << x << endl; // gibt den Wert von x auf der Console aus
}
void printX(int p){
p++;
cout << p << endl; //gibt p in der Console aus
}
In diesem Programm initialisieren wir x mit 1.
Dann wird die Funktion printX aufgerufen.
In dieser Funktion erhöhen wir p um 1 und geben dann den Wert von p(dem Parameter in der Funktion) aus.
Die Ausgabe von printX(x) lautet:
2
Als letztes wird mit cout << x << endl x ausgegeben:
1
Wie man sieht, hat sich am Wert von x nichts geändert, es ist immer noch 1.
Das liegt daran, dass sobald die Funktion printX aufgerufen wird, dem Parameter p der gleiche Wert von x zugewiesen wird, oder anders ausgedrückt, der Funktion wird eine Kopie von x übergeben.
Aber was wenn wir tatsächlich den Wert von x in der Funktion verändern möchten? Dafür brauchen wir dann die Übergabe als Referenz.
Call by reference
Die Übergabe als Referenz ist genau das, eine Referenz auf die Variable. Man kann sie sich auch als alternativen Namen der gleichen Variable vorstellen:
int x = 1;
int &aliasx = x;
Nun können wir wann immer wir x brauchen auch aliasx schreiben:
#include<iostream>
using namespace std;
int main(){
int x = 1; //Variable
int &aliasx = x; //Referenz
cout << x << endl; //gibt x aus
cout << aliasx << endl; //gibt aliasx aus
}
Die Ausgabe in der Console lautet:
1
1
In beiden Fällen erhalten wir den Wert 1, weil es sich im Grunde um die Gleiche Variable handelt nur eben mit einem Alias.
Kommen wir nochmal zur Frage davor zurück:
“Aber was wenn wir tatsächlich den Wert von x in der Funktion verändern möchten?”
Dafür müssen wir am bisherigen Code zwei Änderungen vornehmen.
Und zwar benötigen wir das Kaufmanns-Und( & ), um eine Variable als Referenz auszuzeichnen.
#include<iostream>
using namespace std;
void printX(int &p); // & vor Parameternamen setzen
int main(){
int x = 1;
printX(x);
cout << x << endl;
}
void printX(int &p){ // & vor Parameternamen setzen
p++;
cout << p << endl;
}
p ist jetzt eine Referenz auf x. Die Ausgaben sind jetzt die folgenden:
2
2
Wir haben nun x um 1 auf 2 erhöht.
Vielleicht hast du bereits Erfahrung mit Pointern gesammelt und fragst dich: Wo liegt denn der Unterschied zwischen Referenzen und Pointern? Könnte man nicht auch einfach einen Pointer verwenden? Und dabei liegst du auch nicht falsch. Man kann auch einen stinknormalen Pointer verwenden.
Umsetzung mit Pointer
#include<iostream>
using namespace std;
void printX(int *p); // * vor Parameternamen setzen
int main(){
int x = 1;
printX(&x); // & verwenden, um die Adresse von x zu übergeben.
cout << x << endl;
}
void printX(int *p){ // * vor Parameternamen setzen
(*p)++; // mit Stern dereferenzieren und beides in Klammer setzen.
cout << *p << endl; // * zum dereferenzieren
}
Ausgabe in der Console:
2
2
Auf diese Art haben wir ebenfalls den Wert in x verändert.
Wie du warscheinlich bereits gemerkt hast, müssen wir wesentlich mehr Änderungen vornehmen als bei dem Beispiel mit der Referenz.
Wir brauchen hier den Dereferenzierungsoperator( * ) und den Adressoperator ( & ). Was wir unbedingt beachten müssen ist, dass wir den Pointer immer noch auf etwas anderes verweisen lassen können. Das heißt wir können den Inhalt des Pointers ändern. Bei einer Referenz ist das nicht der Fall.
Wenn wir einmal die Referenz initialisiert haben können wir nicht während der Laufzeit des Programms die Referenz verändern.
Aus diesem Grund müssen wir auch die Referenz direkt initialisieren.
Was ist der Unterschied zwischen einer Referenz und einem Pointer in C++?
Ein Pointer kann genau wie eine Referenz dafür verwendet werden die eigendliche Variable mit Hilfe einer Funktion zu verändern. Jedoch kann der Inhalt eines Pointers(also die Speicherzelle auf die er zeigt) während der Laufzeit geändert werden. Während das bei einer Referenz nicht möglich ist.
Referenz | Pointer |
---|---|
Eine Referenz muss bei der Deklaration auch initialisiert werden. | Ein Pointer muss nicht bei der Deklaration initialisiert werden. |
Eine Referenz ist ein alternativer Name(Alias) für eine Variable in ihr ist nicht die Adresse von der Variablen gespeichert. | Ein Pointer zeigt auf eine Variable indem in ihr die Adresse dieser Variable gespeichert wird. |
Eine Referenz kann nicht NULL sein. | Ein Pointer kann NULL sein. |
Zum Deklarieren einer Referenz brauchen wir das Kaufmanns-Und(&): int x = 1; int &aliasx = x; | Zum Deklarieren eines Pointer brauchen wir den Stern( * ): int x = 1; int *ptr = &x ; Möchten wir den Inhalt des Pointers ausgeben (also die Adresse die in dem Pointer gespeichert wurde) schreiben wir nur den Pointernamen: ptr; Möchten wir auf den Wert zugreifen, auf den der Pointer zeigt, dann müssen wir den Pointer dereferenzieren mit dem Dereferenzierungsoperator( * ), wecher ebenfalls ein Stern ist(überhaupt nicht irritierend…). *ptr; |
Zusammenfassung
- Zum deklarieren einer Referenz verwendet man das Kaufmanns-Und( & )
- Referenzen müssen direkt bei der Deklaration initialisiert werden.
- Ändern wir den Wert der Referenz, so ändert sich der Wert der referenzierten Variable.
- Eine Referenz verhält sich wie ein konstanter Pointer und kann somit nicht während der Laufzeit auf etwas anderes verweisen(eine Referenz ist somit keine Variable).
Hat dir der Inhalt gefallen?
Falls du mehr zu Themen der Informatik lesen willst, kannst du die Suche dafür verwenden:
Du bist der Meinung, das war der Beste Beitrag zum Thema Informatik den du jemals gelesen hast? Dann ist die einzig logische Schlussfolgerung, diesen Beitrag mit deinen Kommilitonen zu teilen. Oder auch nicht mach was du willst, ich bin nicht dein Dad.