In den bisherigen Beispielen wurden aufgerufene Funktionen mit keinem, einem oder mehreren
Parametern versorgt. Mit Hilfe dieser Parameter wurde dann ein Rückgabewert ermittelt, welcher
der aufrufenden Funktion zur Verfügung stand.
Im nachfolgenden Beispiel wird nun versucht, eine Funktion zu schreiben, die die Werte ihrer zwei
Parameter gegeneinander austauscht. Dieses kann nicht mit Hilfe von Return-Werten realisiert
werden:
Programmbeispiel:
#include
#include
void swap(int i, int j);
main () {
int i = 1, j = 10; /* Variablen sofort initialisieren */
printf(\"1 -> i = %d, j = %dn\", i, j)
swap(i, j)
printf(\"3 -> i = %d, j = %dn\", i, j);
} /* Ende main */
void swap(int i, int j) { /* Funktion zum Austauschen */
int c = i; /* Variable c sofort initialisieren */
i = j;
j = c;
printf(\"2 -> i = %d, j = %dn\", i, j);
} /* Ende swap */
Zum Austauschen des Inhaltes der beiden Parameter innerhalb der Funktion swap wird der
\"Parkplatzalgorithmus\" verwendet:
Es wird wie beim Tauschen der Parkplätze zweier Autos verfahren:
Zeiger als Übergabeparameter
Stand: 25.06.04
2
Die Ausgabe des Programms ist:
1 -> i = 1, j = 10
2 -> i = 10, j = 1
3 -> i = 1, j = 10
Der Tauschalgorithmus in swap hat den Inhalt der Variablen korrekt vertauscht, aber die Änderung
war nur lokal innerhalb dieser Funktion. An die aufrufende Funktion ist keine Information über
diese Änderung weitergegeben worden. Der Grund hierfür wird bei näherer Betrachtung des
Übergabemechanismusses von Parametern in C deutlich.
Im RAM (Random Access Memory Speicher
mit wahlfreien Zugriff) wird bei jedem
Programmstart ein Bereich eingerichtet, den
man \"Stack\" nennt. Auf diesem werden unter
anderem die lokalen Variablen abgelegt. Die
Funktion main hat ihre eigenen privaten Daten,
ebenso swap. Bei der Übergabe von Parametern
von der Funktion main an die Funktion swap
werden die Variablen i und j von main noch
einmal auf den Stack kopiert und zwar in den
Bereich, der der Funktion swap zugeordnet ist.
Mit diesen Kopien arbeitet nun die Funktion
swap. Demzufolge besteht hier keine
Möglichkeit, innerhalb der Funktion swap den
Wert der Variablen in der übergeordneten
Funktion main zu ändern. Nur die eigenen
lokalen Variablen (in diesem Fall Kopien der
Variablen von main) können verändert werden.
Es gibt jedoch eine Möglichkeit aus der Funktion swap heraus die lokalen Variablen von main zu
verändern. In C existiert zu jedem Datentyp ein Typ namens Pointer (Zeiger) auf diesen Datentyp.
Ein Pointer ist eine Variable, die als Wert eine Speicheradresse hat.
Zusätzlich ist an einen Pointer noch der Typ der Variablen, die sich an der bezeichneten
Adresse befindet gebunden. Dieses ist notwendig, um korrekt auf das bezeichnete Element
zugreifen zu können.
Wird nun statt einer Variablen ein Pointer auf diese Variable übergeben, so kann über den
Pointer auf die Adresse und damit auch auf die Variable selbst zugegriffen werden.
Im Zusammenhang mit Pointern sind zwei Operatoren von besonderer Bedeutung:
Der Adressoperator & ermittelt die Adresse einer Variablen.
Diese Adresse kann
einer Zeigervariablen zugewiesen oder
als Parameter übergeben werden.
Mit dem \"Dereferenzierungsoperator\" kann über die Adresse auf den verwiesenen Wert
zugegriffen werden.
Zeiger als Übergabeparameter
Stand: 25.06.04
3
Die Variablen c,i und j seien vom Typ int, so dass...
der Ausdruck \"c = *i;\" bedeutet: \"Nimm den Inhalt der Speicherstelle, auf die i zeigt und
weise ihn der Variablen c zu, und zwar auf der Breite eines int.\"
der Ausdruck \"*j = c;\" bedeutet: \"Weise den Inhalt der Variablen c der Speicherstelle zu,
auf die j zeigt, und zwar auf der Breite eines int.
Programm-Beispiel:
#include
#include
void swap(int *i, int *j);
main() {
int i = 1,j = 10; /* Variablen sofort initialisieren */
printf(\"1 -> i = %d, j = %dn\", i, j);
swap(&i, &j);
printf(\"3 -> i = %d, j = %dn\", i, j);
} /* Ende main */
void swap(int *i, int *j){ /* Funktion zum Austauschen */
int c = *i; /* Variable c sofort initialisieren */
*i = *j;
*j = c;
printf(\"2 -> *i = %d, *j = %dn\", *i, *j);
printf(\"2 -> i = %lu, j = %lun\", (unsigned long) i,
(unsigned long) j);
} /* Ende swap */
Im folgenden Diagramm ist der
Übergabemechanismus mit
Pointern noch einmal grafisch
dargestellt:
Der Funktion swap werden
die Adressen der Variablen
übergeben, die dann zur
Manipulation der
Originalwerte benutzt werden
können.
Zeiger als Übergabeparameter
Stand: 25.06.04
4
Die Deklaration von Pointern sieht folgendermaßen aus:
*
Beispiel:
int *p_i; /* Deklaration von p_i als Zeiger auf einen int-Wert */
char *s; /* Dekl. von s als Zeiger auf ein char */
/* (als String) */
ELEM2D *pElem; /* Dekl. von pElem als Zeiger auf eine Struktur ELEM2D */
Aufgabe: Programmieren Sie eine Funktion, die den Mittelwert zweier int -Werte berechnet.
Lesen Sie in der Funktion main zwei Werte per Tastatur ein und verwenden Sie folgenden
Funktions-Prototyp:
void mittelwert(int a, int b, double *mittel);
|