ein Kapitel zurück                                           ein Kapitel weiter

Dieses Kapitel setzt voraus das sie das vorherige Kapitel über Zeiger verstanden haben. Ich möchte mich in diesem Kapitel mit weiteren Themen befassen wo sich Zeiger überall einsetzen lassen.

Zeiger als Funktionsparameter in Funktionen
Funktionen ,denen wir einen oder mehrere Paremeter übergeben haben und die uns mittels return wieder einen Rückgabewert lieferten, haben wir ja schon kennen gelernt. Man spricht in diesem Fall ja von CALL BY VALUE. Der Nachteil an dieser Methode war ja, dass bei einem Aufruf einer Funktion, erst mal alle Parameter kopiert werden mussten, so das diese Variablen der Funktion anschließend als lokale Variablen zur Verfügung standen. Beispielsweise folgendes Programm....

/*Download:ze1.c*/
#include <stdio.h>
#define PI 3.14

float kreisflaeche(float wert)
{
return (wert=wert * wert * PI);
}

int main()
{
float radius;
float flaeche;
printf("Berrechnung einer Kreisfläche!!\n\n");
printf("Bitte den Radius eingeben : ");
scanf("%f",&radius);

flaeche=kreisflaeche(radius);

printf("\nDie Kreisfläche beträgt : %f\n",flaeche);

return 0;
}

Nun da wir im Kapitel zuvor schon die Verwendung von Zeigern und Adressen kennen gelernt haben, könnten wir dies doch auch auf unsere Funktionsparamter verwenden. Wir müssten doch einfach unserer Funktion kreisfläche(), die Adresse des Radius des Kreises übergeben und in der Funktion dann mit dem Dereferenzierungsoperator (*) arbeiten, der ja auf den Wert der Adresse zeigt. Dies Methode nennt man CALL BY REFERENCE.
Wollen wir unser Programm nun mit der CALL BY REFERENCE Methode ansehen......

/*Download:ze2.c*/
#include <stdio.h>
#define PI 3.14

void kreisflaeche(float *wert)
{
*wert= (*wert) * (*wert) * PI;
}

int main()
{
float radius;
printf("Berrechnung einer Kreisfläche!!\n");
printf("...............................\n");
printf("Bitte den Radius eingeben : ");
scanf("%f",&radius);

kreisflaeche(&radius);

printf("\nDie Kreisfläche beträgt : %f\n",radius);

return 0;
}





In unserem Beispiel übergeben wir mit dem Funktionsaufruf....

kreisflaeche(&radius);

...die Adresse unserer Variablen 'radius' an die Funktion...

void kreisflaeche(float *wert)

In unserer Funktion 'kreisflaeche()' haben wir als Parameter einen Zeiger Namens 'wert' vom Typ float. Nun wie wir in unserem vorherigen Kapitel gelernt haben zeigen Zeiger die wir an dem Dereferenzierungsoperator erkennen auf Adressen Ihres Typen. Unser Zeiger in der Funktion 'kreisflaeche' bekommt durch den Funktionsaufruf 'kreisflache(&radius)' die Adresse von der Variablen 'radius' zugewiesen. Jetzt da unsere Zeiger in der Funktion die Adresse kennt können wir mit dieser Adresse in der der Wert von dem Radius steht rechnen....

*wert= (*wert) * (*wert) * PI;

Die Klammern bei der Berechnung können sie auch weglassen, sie dienen nur zur besseren Übersicht. Logischerweise müssen sie diese Berechnung mit dem Dereferenzierungsoperator durchführen, da nur mit dem '*' auf dem Wert zugegriffen wird dessen Adresse in unserem Zeiger 'wert' steht. Ohne unserem Dereferenzierungsoperator '*' würden sie lediglich mit der Adresse rechnen. Die meisten Compiler geben ohnehin eine Fehlermeldung aus. Falls sie das nicht verstanden haben möchte ich sie nochmals auf das vorherige Kapitel verweisen. Was Ihnen jetzt sicherlich auch noch auffallen dürfte ist, das bei unserer Funktion keine Rückgabe mittels 'return' erfolgt und unsere Funktion vom Typ 'void' ist und die Rechnung trotzdem ausführt. Nun das liegt daran das bei jeder Neuübersetzung des Programms jede Variable eine Adresse zugewiesen bekommt die sich während der Laufzeit des Programms nicht mehr ändern lässt. Und da unserer Funktion eh die Adresse einer Variablen (radius) bekommen hat und sie mit dem Dereferenzierungsoperator '*' mit dem Wert dieser Variablen(radius) rechnet, wird dieser Wert ja auch verrändert der in der Adresse von 'radius' steht auf den unser Zeiger zeigt. Und aus diesem Grund würde zum Beispiel wenn wir unser Programm ohne Zeiger und Adressenübergabe schreiben würden wie...

/*Download:ze3.c*/
#include <stdio.h>
#define PI 3.14

void kreisflaeche(float wert)
{
wert= wert * wert * PI;
}

int main()
{
float radius;
printf("Berrechnung einer Kreisfläche!!\n");
printf("...............................\n");
printf("Bitte den Radius eingeben : ");
scanf("%f",&radius);

kreisflaeche(radius);

printf("\nDie Kreisfläche beträgt : %f\n",radius);

return 0;
}

...würde auch laufen nur wird als Ergebnis immer der Wert ausgegeben den sie für 'radius' eingegeben haben. Sogar die Berechnung wird dabei ausgeführt nur steht in diesem Fall das Ergebnis in der Variablen 'int wert' die in irgendeiner anderen Adresse vorliegt die ihm zugewiesen wurde, nämlich der Adresse von 'wert'. Dann müssten sie schon....

printf("%f",wert);

...in der Funktion 'kreisflaeche()' hinzufügen. Ich sag es nochmals, es ist wichtig das sie den Bezug zwischen Zeigern und Adressen verstehen.

Aufgabe
Warum funktioniert das Programm nicht? Tipp: Der Fehler ist in der Funktion 'maxwert' !!

/*Download:ze4.c*/
#include <stdio.h>

int *maxi;

void maxwert(int *wert1, int *wert2)
{
maxi = (((*wert1)>(*wert2)) ? (*wert1) : (*wert2));
}

int main()
{
int zahl1,zahl2;

printf("Bitte Zahl 1: ");
scanf("%d",&zahl1);
printf("Bitte Zahl 2: ");
scanf("%d",&zahl2);

maxwert(&zahl1,&zahl2);

printf("Der größere Wert = %d\n",*maxi);

return 0;
}

Hier gehts zur Lösung!

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf