Referenzparameter
# Referenzparameter

Referenzparameter (englisch call by reference oder pass by reference) sind Parameter von Unterprogrammen in Programmiersprachen, mittels derer ein Unterprogramm die übergebenen Argumente wie dessen übergeordnetes Programm verwenden und ändern kann. Jede Veränderung bleibt auch nach Verlassen des Unterprogramms erhalten, da keine Kopien für das Unterprogramm erzeugt werden. Der Nachteil hierbei besteht darin, dass eine ungewollte Beeinflussung von Hauptprogrammvariablen im Unterprogramm möglich ist. Der 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 (Verweis, Alias) aufgefasst werden kann.

Normalerweise stehen neben Referenzparametern auch Wertparameter zur Verfügung, seltener Wertergebnisparameter.

## Beispiel

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

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++:

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 8) übergeben werden. Anschließend hat die Funktion den Wert quadriert 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 N übergeben.

| | Referenzparameter | Wertparameter |
| - | - | - |
| formale Parameter | einfache Variablen und strukturierte Variablen | einfache Variablen und strukturierte Variablen |
| tatsächliche Parameter | nur Variablen, Felder, Feldelemente, Strukturelemente mit genau passendem Datentyp; keine Konstanten und Ausdrücke | beliebige Ausdrücke wie 1.0, 2*X, sin(x) oder auch Typumwandlungen |
| Ü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.

In Zeile 15 wird der Adressoperator & verwendet, so dass die Adresse der Variablen x an die Funktion übergeben wird. Diese wird an den Zeigerparameterp (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:

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

Bei der Variante increment_r entfallen also die Zeigerdereferenzierungen im Funktionsrumpf.

Aufruf der Funktion:

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

## Verwendende Programmiersprachen

* Pascal
* Modula-2
* Fortran
* C++
* PL/I
* PHP
