|
Zeiger als Übergabeparameter
In den vorherigen Beispielen wurden aufgerufene Funktionen mit keiner, einer oder mehreren Funktionen versehen.
Parameter. Diese Parameter wurden verwendet, um den Rückgabewert zu bestimmen, der der aufrufenden Funktion zur Verfügung steht. Im folgenden Beispiel wird versucht, eine Funktion zu schreiben, die die Werte ihrer beiden Werte tauscht.
Parameter untereinander. Dies kann mit Hilfe von Rückgabewerten nicht realisiert werden: Beispielprogramm: } /* Ende main */ void swap(int i, int j) { /* Funktion zum Ersetzen */ int c = i; /* Variable c sofort initialisieren */ i = j; j = c; printf(“2 -> i = %d, j = %d\n”, i, j); } /* End swap */ Der “Parkraumalgorithmus” dient dazu, den Inhalt der beiden Parameter innerhalb der Swap-Funktion auszutauschen: Das Verfahren ist das gleiche wie das Austauschen der Parkplätze von zwei Autos: Zeiger als Übertragungsparameter Status: 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 Swap-Algorithmus im Swap hat den Inhalt der Variablen korrekt getauscht, aber die Änderung war nur lokal innerhalb dieser Funktion. Es wurden keine Informationen über diese Änderung an die aufrufende Funktion weitergegeben. Der Grund dafür wird bei genauerer Betrachtung des Übertragungsmechanismus von Parametern in C deutlich. Im RAM (Random Acce
ss Memory) wird bei jedem Programmstart ein Bereich namens “Stack” eingerichtet, der häufig verwendete Programmanweisungen zur Erhöhung der allgemeinen Geschwindigkeit eines Systems speichert. Hier werden unter anderem die lokalen Variablen gespeichert. Die Hauptfunktion hat ihre eigenen privaten Daten, sowie den Austausch. Wenn Parameter von der Hauptfunktion an die Swap-Funktion übergeben werden, werden die Variablen i und j wieder von der Hauptfunktion auf den Stapel in dem der Swap-Funktion zugeordneten Bereich kopiert. Die Swap-Funktion funktioniert nun mit diesen Kopien. Infolgedessen gibt es keine Möglichkeit, den Wert der Variablen in der übergeordneten Funktion main innerhalb der Swap-Funktion zu ändern. Es können nur die eigenen lokalen Variablen (in diesem Fall Kopien der Hauptvariablen) geändert werden. Es besteht jedoch die Möglichkeit, die lokalen Variablen von main aus der Swap-Funktion zu ändern. In C hat jeder Datentyp einen Typ, der als Pointer auf diesen Datentyp bezeichnet wird. Darüber hinaus ist der Variablentyp, der sich an der angegebenen Adresse befindet, an einen Zeiger gebunden. Dies ist notwendig, um auf das angegebene Element korrekt zugreifen zu können. Wird anstelle einer Variablen ein Pointer auf diese Variable übergeben, kann mit dem Pointer auf die Adresse und damit auf die Variable selbst zugegriffen werden. Zwei Operatoren sind im Zusammenhang mit Zeigern von besonderer Bedeutung: Der Adressoperator & bestimmt die Adresse einer Variablen. Diese Adresse kann einer Zeigervariablen zugewiesen oder als Parameter an . übergeben werden. Mit dem “Dereferenzierungsoperator” kann über die Adresse auf den referenzierten Wert zugegriffen werden. Zeiger als Übertragungsparameter Status: 25.06.04 3 Die Variablen c,i und j sind vom Typ int, so dass die….. bedeutet der Ausdruck “c = *i;”: “Nimm den Inhalt des Speicherplatzes, auf den i zeigt, und weise ihn der Variablen c, in der Breite eines int. zu”. bedeutet der Ausdruck “*j = c;”: /* Ende main */ void swap(int *i, int *j){ /* Funktion zum Ersetzen */ int c = *i; /* Variable c sofort initialisieren */ *i = *j; *j = c; printf( (Printf-Formatstring bezieht sich auf einen Steuerparameter, der von einer Klasse von Funktionen in den Zeichenkettenverarbeitungsbibliotheken verschiedener Programmiersprachen verwendet wird) “2 -> *i = %d, *j = %d\n”, *i, *j); printf(“2 -> i = %lu, j = %lu\n”, (unsigned long) i, < (unsigned long) j); } /* Ende des Austausches */ Im folgenden Diagramm wird der Übertragungsmechanismus mit Zeigern nochmals grafisch dargestellt : Die Auslagerungsfunktion empfängt die Adressen der Variablen, mit denen dann die Originalwerte manipuliert werden können. Zeiger als Übertragungsparameter Status: 25.06.04 4 Die Deklaration der Zeiger sieht so aus: * Beispiel: int *p_i; /* Deklaration von p_i als Zeiger auf einen int-Wert */ char *s; /* Deklaration von s als Zeiger auf ein Zeichen */ /* (als Zeichenkette) */ ELEM2D *pElem; /* Dekl. von pElem als Zeiger auf eine Struktur ELEM2D */ Aufgabe: Programmieren Sie eine Funktion, die den Mittelwert von zwei Int-Werten berechnet. Lesen Sie in der Hauptfunktion zwei Werte von der Tastatur und verwenden Sie den folgenden Funktionsprototyp (In der Computerprogrammierung ist ein Funktionsprototyp oder eine Funktionsschnittstelle eine Deklaration einer Funktion, die den Namen und die Typensignatur der Funktion angibt, aber den Funktionskörper weglässt): : void mean(int a, int b, double *mean).