Call by reference


Call by reference

Referenzparameter (engl. call by reference) sind Parameter von Unterprogrammen in Programmiersprachen, die die Übergabe und Rückgabe von Werten ermöglichen. Ihr Name kommt daher, dass der Compiler in den meisten Programmiersprachen die Adresse des Speicherbereichs einer Variablen oder eines Feldelements übergibt (also einen Zeiger auf die Variable oder das Feldelement), die als Referenz aufgefasst werden kann.

Beim Aufruf des Unterprogramms wird die Adresse im formalen Parameter gespeichert. Jede Operation mit diesem formalen Parameter wirkt sofort auf den tatsächlichen Parameter und bleibt auch nach Verlassen des Unterprogramms erhalten. Der Nachteil hierbei besteht darin, dass eine unbewusste Beeinflussung von Hauptprogrammvariablen im Unterprogramm möglich ist.

Normalerweise stehen neben Referenzparametern auch Wertparameter zur Verfügung, die die Übergabe von Ausdrücken erlauben, jedoch keine Rückgabe von Werten.

Inhaltsverzeichnis

Beispiel

In der Sprache Pascal muss beim Unterprogrammaufruf für jeden Referenzparameter eine Variable, ein Feld- oder Strukturelement als tatsächlicher Parameter angegeben werden:

  1. (* Uebergabe der Variablen X als Referenzparameter in PASCAL *)
  2. PROGRAM Demo(input,output);
  3.  
  4. PROCEDURE Inkrementiere(VAR N: Integer);
  5. BEGIN
  6.    N:=N+1;
  7. END;
  8.  
  9. VAR X: integer;
  10. BEGIN
  11.    Write('Bitte X eingeben'); ReadLn(X);
  12.    Inkrementiere(X);
  13.    Write('Der Nachfolger von X ist: '); WriteLn(X);
  14. END.

Die Funktion Inkrementiere hat den Referenzparameter N (Zeile 4), der in Zeile 13 durch die Variable X als tatsächlicher Parameter X ersetzt wird. Die Unterprogramme Write und WriteLn (Zeilen 11 und 13) verwenden Wertparameter, während ReadLn einen Referenzparameter verlangt (Zeile 11), für den hier auch X eingesetzt wird. Dadurch ist z. B. WriteLn(2*X) ohne Weiteres möglich, während ReadLn(2*X) einen Syntaxfehler bei der Übersetzung erzeugt.

Hier ein kleines Beispiel in C++:

  1. #include <iostream>
  2. #include <string>
  3. #include <cmath>
  4.  
  5. using namespace std;
  6.  
  7. void do_the_square(double& square_meters){
  8.    square_meters=pow(square_meters,2);
  9. }
  10.  
  11. int main(){
  12.    double value = 2;
  13.    do_the_square(value);
  14.    cout << "The square_meters are: " << value << endl;
  15.    system("pause");
  16.    return 0;
  17. }

Die Funktion do_the_square() arbeitet hier auch mit einer Referenz, und da eine Referenz nur ein Verweis auf eine Variable ist und so kein Wert zurückgegeben werden muss, reicht es, hier im Kopf der Funktion einmal eine Referenz zu setzen.

Beim Aufruf der Funktion muss nur der Wert value (Zeile 12) übergeben werden. Anschließend hat die Funktion die Quadratmeter berechnet und value diesen Wert über den Verweis angenommen.

Formale und tatsächliche Parameter

Im Beispiel wird der Referenzparameter N (Schlüsselwort VAR) verwendet, der bei der Deklaration des Unterprogramms erzeugt wird. Wird VAR weggelassen, so wird ein Wertparameter erzeugt. Beim Aufruf wird der tatsächliche Parameter X übergeben.

Referenzparameter Wertparameter
formale Parameter einfache Variablen und strukturierte Variablen einfache Variablen und strukturierte Variablen
tatsächliche Parameter nur Variablen, Felder, Feldelemente, Strukturelemente; keine Konstanten und Ausdrücke beliebige Ausdrücke wie 1.0, 2*X, sin(x), y[i]
Übergabe Als Adresse übergeben (geringer Aufwand bei Feldern) Als Kopie (hoher Aufwand bei Feldern)
Zuweisung innerhalb Unterprogramm möglich möglich oder verboten (je nach Programmiersprache)
Rückgabe des Wertes bei Unterprogrammende ja nein

Moderne (optimierende) Compiler können bei Übergabe von Wertparametern ermitteln, ob eine Kopie nötig ist und gegebenenfalls darauf verzichten.

Simulation von Referenzparametern durch Zeiger

Das folgende Beispiel ist in der Sprache C geschrieben, welche keine Referenzparameter kennt. Durch Benutzung von Zeigern kann aber ein ähnliches Verhalten realisiert werden.

  1 /* Uebergabe der Variablen x als Zeigerparameter p in C */
  2
  3 #include <stdio.h>
  4    
  5 void increment_p(int* p)
  6 {
  7    (*p) = (*p) + 1;
  8 }
  9
 11
 12 int main()
 13 {
 14    int x;
 15    x = 3;
 16
 17    increment_p(&x); 
 18    printf("Das Ergebnis ist %d\n", x);
 19 }

In Zeile 17 wird der Adressoperator & verwendet, so dass die Adresse der Variablen x an die Funktion übergeben wird. Diese wird an den Zeigerparameter p (Zeile 5) übergeben.

Referenzparameter in Form von Referenzen

In der Sprache C++ können Referenzparameter ebenso wie in C als Zeiger realisiert werden. Es wurde aber auch eine Spracherweiterung eigens zu diesem Zweck eingeführt. Diese Spracherweiterung nennt sich Referenz und hat folgende Notation:

 void increment_r(int& r)
 {
    r = r + 1;
 }

Im Vergleich dazu noch einmal das Beispiel für Zeiger:

 void increment_p(int* p)
 {
    (*p) = (*p) + 1;
 }

Bei der Variante increment_r entfallen also die Zeigerdereferenzierungen im Funktionsrumpf.

Aufruf der Funktion:

 ...
 increment_r(x); 
 ...

Im Unterschied zu der Variante mit increment_p wird also hier beim Aufruf nicht der Adressoperator & verwendet.

Sonderfall Java

In der Sprache Java wird bei primitiven Datentypen automatisch ein Wertparameter verwendet. Bei Objekten wird die Objektreferenz als Wertparameter übergeben. Die aufgerufene Methode kann also den Zustand des referenzierten Objekts verändern, jedoch nicht die Referenz selbst – sie zeigt also nach der Rückkehr aus dem Methodenaufruf auf dasselbe Objekt wie zuvor. Die Terminologie vieler Java-Publikationen verdeckt diesen Umstand.[1] [2]

Dies zeigt folgendes Beispiel:

import java.util.Date;
public class Test {
    public static void main(String args[]) {
        Date s = new Date(100000000000l);
        System.out.println("main 1: " + s);
        call(s);
        System.out.println("main 2: " + s);
    }
    public static void call(Date s) {
        System.out.println("call 1: " + s);
        s.setTime(200000000000l);
        System.out.println("call 2: " + s);
    }
}

Die Ausgabe ist:

 main 1: Sat Mar 03 10:46:40 CET 1973
 call 1: Sat Mar 03 10:46:40 CET 1973
 call 2: Mon May 03 20:33:20 CET 1976
 main 2: Mon May 03 20:33:20 CET 1976

Allerdings wird eine geänderte Referenz nicht zurückgegeben. Dies verdeutlicht folgendes Beispiel:

import java.util.Date;
public class Test {
    public static void main(String args[]) {
        Date s = new Date(100000000000l);
        System.out.println("main 1: " + s);
        call(s);
        System.out.println("main 2: " + s);
    }
    public static void call(Date s) {
        System.out.println("call 1: " + s);
        s = new Date(200000000000l);
        System.out.println("call 2: " + s);
    }
}

Die Ausgabe ist:

 main 1: Sat Mar 03 10:46:40 CET 1973
 call 1: Sat Mar 03 10:46:40 CET 1973
 call 2: Mon May 03 20:33:20 CET 1976
 main 2: Sat Mar 03 10:46:40 CET 1973

Quellen

  1. http://www.ibm.com/developerworks/java/library/j-passbyval/
  2. http://javadude.com/articles/passbyvalue.htm

Verwendende Programmiersprachen

Siehe auch


Wikimedia Foundation.

Schlagen Sie auch in anderen Wörterbüchern nach:

  • call-by-reference — noun An in which the arguments to a function are evaluated first, and a pointer to the result is passed to the function. , call by value , call by name , call by need , call by future …   Wiktionary

  • Reference (computer science) — This article is about a general notion of reference in computing. For the more specific notion of reference used in C++, see Reference (C++). In computer science, a reference is a value that enables a program to indirectly access a particular… …   Wikipedia

  • Call by Value — Wertparameter (engl. call by value) sind Parameter von Unterprogrammen in Programmiersprachen, die die Übergabe, jedoch nicht die Rückgabe von Werten ermöglichen. Neben Wertparametern stehen oft auch Referenzparameter zur Verfügung, die neben… …   Deutsch Wikipedia

  • Call by value — Wertparameter (engl. call by value) sind Parameter von Unterprogrammen in Programmiersprachen, die die Übergabe, jedoch nicht die Rückgabe von Werten ermöglichen. Neben Wertparametern stehen oft auch Referenzparameter zur Verfügung, die neben… …   Deutsch Wikipedia

  • Call Of Duty 2 — Éditeur Activision Développeur Infinity Ward …   Wikipédia en Français

  • Call of duty 2 — Éditeur Activision Développeur Infinity Ward …   Wikipédia en Français

  • Call Off The Search — ██████████ …   Wikipédia en Français

  • Call off the search — ██████████ …   Wikipédia en Français

  • Call of Duty 2 — Éditeur Activision Développeur Infinity Ward Date de sor …   Wikipédia en Français

  • Call signs in North America — are frequently still used by North American broadcast stations in addition to amateur radio and other international radio stations that continue to identify by call signs around the world. Each country has a different set of patterns for its own… …   Wikipedia