Einzelnen Beitrag anzeigen
Alt 22.08.2001, 22:22   #6
kikakater
Inventar
 
Registriert seit: 24.01.2001
Beiträge: 5.631


Standard

1) Call by Value: Übergabe des Wertes einer Variablen
2) Call by Reference: Übergabe der Adresse einer Variablen, Arbeiten innerhalb der Unterroutine wie mit einer Datenvariablen IM GEGENSATZ zu einer Zeigervariablen
3) Call by Address: Übergabe der Adresse einer Variablen

Also:

a) Aufruf der C-Funktion "unterprogramm":

ad 1: int i=400;
unterprogramm(i); /* Übergabe des Wertes von i (also dem dezimalen Wert 400) über den Stack an die Funktion "unterprogramm" */

ad 2: int i=400;
unterprogramm(i); /* Übergabe der Referenz (=Adresse) von i, implizit die Adresse von i */

ad 3: int i=400;
unterprogramm(&i); /* Übergabe der (Zeiger-) Adresse von i, explizit die Adresse von i */


b) Ausdefinition der C-Funktion "unterprogramm":

ad 1:
int unterprogramm(int value) /* Variablenwert liegt auf dem Stack */
{
if(value==400) return value * 2;
if(value<400) value=0; /* hat keinen Effekt auf die Variable i, insofern ist das ein versteckter Fehler falls i außerhalb verändert werden sollte */
}

ad 2:
int unterprogramm(int& outervariable) /* Referenz(=Adresse der Variable) liegt auf dem Stack */
{
if(outervariable==400) return outervariable * 2;
if(outervariable<400) outervariable=0; /* i wird verändert, outervariable und i haben die gleiche Speicheradresse */
}

ad 3:
int unterprogramm(int *pointer) /* Adresse (einer int Variablen) liegt auf dem Stack */
{
if(*pointer==400) return *pointer * 2; /* i wird über * auf i verändert, "i" ist "*pointer" in diesem Fall bzw. "*pointer" ist "i" besser gesagt */
if(*pointer<400) *pointer=0; /* i wird über *pointer= verändert */
}

Während 2. und 3. vom Speicherzugriff gleich sind und direkt auf die Variable der aufrufenden Funktion wirken, beschränkt sich 1. auf die Parametervariable value, es handelt sich um eine echte "Wert"-Kopie einer Integer-Variablen.

Call by Reference ist dazu da um den Zugriff auf Variablen innerhalb einer UNTERROUTINE genauso zu ermöglichen, als ob die Anweisungen in der aufrufenden Routine stehen würden.

Also statt *pointer= kann man value= benutzen in dieser Unterroutine, anstatt einen Wert zu übergeben, wird die Adresse ... die Referenz .. die Referenzadresse ... der Variablen übergeben und syntaxmäßig aber wie mit einer Wertvariablen und eben nicht wie mit einer Zeigervariablen gearbeitet.

Bei einer 2 Byte int Variable scheint die Sache Call by Reference unwirtschaftlicher zu sein - ist sie im Übrigen auch - es werden 4 Bytes statt 2 auf dem Stack übergeben.

Der erste Vorteil liegt in der gleichen Schreibweise wie bei einer Wertvariablen und bei der unmittelbaren Veränderung der übergebenen Variable selbst.

Der zweite Vorteil liegt in der Übergabe einer Adresse wie bei einer Pointervariante dieser Funktion - also "int unterprogramm(int *pointer)" - und nicht - wenn es sich beim Funktionsparameter um eine Struktur handeln würde - z.B. einer 456 Byte großen Struktur ... SOWIE ... dem bequemen Ansprechen als Datenvariable und nicht Zeigervariable + Sternbackreferencing auf ein Datum (=grammatikalische Einzahl des Wortes "Daten", nicht notwendigerweise ist damit ein Tagesdatum gemeint).

Es wird deshalb nicht diese gesamte Länge von 456 Bytes (="der Wert" der Struktur) auf dem Stack mitgegeben, sondern nur die Adresse der Struktur, arbeiten tut die Funktion dann also trotz vermeintlicher syntaxmäßiger Wertkopie-Verwendung eines Funktionsparameters mit der übergebenen Struktur(adresse) direkt.

pointer_auf_struktur->membervariable= 1234; entfällt somit und lautet nun referenz_auf_struktur.membervariable= 1234; in der Funktion mit dem Funktionskopf int funktion(struct struktur& referenz_auf_struktur) .

Call by reference ist von der Syntax (=Grammatik) her wie die Verwendung einer Wertvariablen und semantisch (bedeutungsmäßig) ein Zugriff über Adresse auf die außerhalb der Funktion gelegene Variable.

mfg Kikakater
kikakater ist offline   Mit Zitat antworten