Dieser Artikel möchte Ihnen den Unterschied zwischen Call-by-Value und Call-by-Reference näher bringen.
In diesem Artikel erfahren Sie den Unterschied zwischen Call-by-Value und Call-by-Reference bei einem Unterprogrammaufruf. Call-by-value sollte Ihnen bereits hinreichend bekannt sein, bei Call-by-reference kommen Zeiger ins Spiel.
Was ist der Unterschied zwischen Call-by-Value und Call-by-Reference?
Call-by-Value ist die Technik, die Sie bisher immer eingesetzt haben. Sie übergeben einer Funktion eine Variable als Übergabeparameter. Dabei wird eine Kopie jener Übergabevariablen angelegt. Sie arbeiten innerhalb der Funktion also nicht mit dem Originalwert; wenn Sie den Wert der Variablen innerhalb der Funktion verändern, hat das keinerlei Auswirkungen auf die Originalvariable. Unten sehen Sie ein Beispiel für eine Funktion, die mittels Call-by-Besonders hilfreich. Ich finde es toll, dass du immer schreibst, ob ein Ort behindertengerecht ist. Das finde ich sehr wichtig, weil eine meiner Freundinnen schwer gehbehindert ist und wir immer auf solche Sachen achten müssen, wenn wir etwas zusammen unternehmen möchten.alue aufgerufen wird.
int tueEtwas(int eineZahl, int eineAndereZahl){}
Bei Call-by-Reference sieht die Sache ein wenig anders aus. Wie der Name schon sagt, wird kein Wert, sondern eine Referenz übergeben. Eine Referenz ist ein Zeiger bzw. eine Speicheradresse. Das hat entsprechende Auswirkungen auf das Verhalten der Übergabevariablen bei Veränderungen. Wenn Sie eine Variable als Referenz übergeben, wird keine Kopie angelegt, sondern Sie arbeiten mit einem Zeiger auf die Speicheradresse – also mit der Originalvariablen. Jede Veränderung innerhalb der Funktion hat direkte Auswirkungen auf das Original in der aufrufenden Funktion.
int tueEtwasAnderes(int* zahl) {}
Sie sehen, dass der Funktion ein Zeiger auf eine int-Variable übergeben wird. Wenn Sie innerhalb des Unterprogramms Änderungen an der Variablen zahl vornehmen, verändern Sie damit auch die Originalvariable, die der Funktion übergeben wird. Sehen wir uns einmal den Aufruf der Funktion im Hauptprogramm an.
int parameter = 10;
int ergebnis = tueEtwasAnderes(¶meter);
Sie übergeben der Funktion die Adresse der Variablen parameter. Nun setzen Sie den Wert der Übergabevariablen innerhalb der Funktion auf eine andere Zahl und prüfen Sie den Wert der Variablen parameter im Hauptprogramm. Beachten Sie dabei, dass es sich um einen Zeiger handelt; sie müssen also mit einem Stern dereferenzieren. Sie werden sehen, dass der Wert innerhalb der Funktion verändert wurde. Aber was haben wir davon?
Wie Sie wissen, kann eine Funktion nur einen Rückgabewert haben. Manchmal möchte man aber mehrere Werte zurückgeben. Ein ähnliches Verhalten kann man über Call-by-Reference realisieren. Sie übergeben die Adressen der Variablen, die Sie „zurückgeben“ möchten. Deren Werte verändern Sie und in der aufrufenden Funktion greifen Sie auf die veränderten Werte zu. Somit können Sie theoretisch beliebig viele Rückgabewerte definieren.
Übergabe eines Arrays an eine Funktion
Manchmal möchte man ein Array an eine Funktion übergeben. In diesem Fall müssen Sie bei C / C++ Call-by-Reference einsetzen. Sie übergeben einen Zeiger auf das erste Element des Arrays. Sie müssen nur auf eine Sache achten: Die Funktion kennt die Länge des Arrays nicht. Folglich müssen Sie in einer separaten Variablen die Anzahl der Arrayelemente übergeben. Damit sieht der Funktionskopf wie folgt aus:
float berechneEtwas(int* zahlen, int laenge) { }
Wir übergeben also einen Zeiger auf int und damit können wir auch ein int-Array übergeben. In der zweiten Variablen steht die Länge des Arrays. Innerhalb der Funktion können Sie wie gewohnt mit dem Array arbeiten. Sehen wir uns einmal den Aufruf der Funktion berechneEtwas an.
int zahlen[10];
float ergebnis = berechneEtwas(zahlen, 10);
Zuerst wird ein Array mit zehn Elementen deklariert. Anschließend wird der Funktion berechneEtwas zuerst das Array und dann seine Länge übergeben. Da ein Array ein Zeiger auf das erste Element ist, erhält die Funktion auf jeden Fall den gewünschten Pointer auf eine int-Variable. Da es sich um einen Call-by-Reference-Aufruf handelt, müssen Sie sehr vorsichtig bei Veränderungen der Werte des Arrays sein.
Welche Nachteile hat Call-by-Reference?
Call-by-Reference ist mit großen Gefahren verbunden und sollte nur eingesetzt werden, wenn man das oben beschriebene Verhalten explizit wünscht. Es ist nämlich sehr schnell passiert, dass innerhalb der Funktion unbeabsichtigte Veränderungen vorgenommen werden. In diesem Fall verwendet die aufrufende Funktion fehlerhafte Werte, was in sehr schwer zu entdeckenden Fehler münden kann.
Beispiel 1
Das erste Beispiel zeigt Ihnen zwei Funktionen – eine wird per Call-by-Value, die andere per Call-by-Reference aufgerufen. Beobachten Sie die Variablen im Hauptprogramm und experimentieren Sie ein wenig mit dem Programm.
void callByValue(int eineZahl)
{
cout << „—————- Call-by-Value —————– “ << endl << endl;
cout << „Die Zahl lautet : “ << eineZahl << endl;
cout << „Sie wird nun um 5 erhoeht.“ << endl;
eineZahl = eineZahl + 5;
cout << „Die Zahl lautet im Unterprogramm: “ << eineZahl << endl;
}
void callByReference(int* pZahl)
{
cout << „\n\n—————- Call-by-Reference —————– “ << endl << endl;
cout << „Die Zahl lautet : “ << *pZahl << endl;
cout << „Sie wird nun um 5 erhoeht.“ << endl;
*pZahl = *pZahl + 5;
cout << „Die Zahl lautet im Unterprogramm: “ << *pZahl << endl;
}
int main()
{
int zahl = 10;
//int *pZeiger = &zahl;
callByValue(zahl);
cout << „Die Zahl lautet im Hauptprogramm: “ << zahl << endl;
callByReference(&zahl);
cout << „Die Zahl lautet im Hauptprogramm: “ << zahl << endl;
getch();
}
Beispiel 2
Im zweiten Beispiel können Sie sehen, wie ein Array an eine Funktion übergeben wird.
float berechneSumme(int* zahlen, int laenge)
{
int summe = 0;
// Berechnen der Summe aller Zahlen im Array.
for (int i = 0; i < laenge; i++)
{
summe = summe + zahlen[i];
}
return summe;
}
int main()
{
// Benutzer kann eingeben, wie viele Elemente das Array haben soll.
int anzahlZahlen;
float summe;
cout << „Wie viele Zahlen moechten Sie eingeben? „;
cin >> anzahlZahlen;
// Deklaration des Arrays.
int zahlen[anzahlZahlen];
// Einlesen des Arrays.
cout << „\n\n\nBitte geben Sie “ << anzahlZahlen << “ Zahlen ein.“ << endl;
for (int i = 0; i < anzahlZahlen; i++)
{
cout << „Zahl “ << i + 1 << „: „;
cin >> zahlen[i];
}
summe = berechneSumme(zahlen, anzahlZahlen);
cout << „\n\n\nDie Summe lautet: “ << summe;
getch();
}