7.5    Rückgabewert von Funktionen

In der Praxis erstellen Sie sehr oft Funktionen, die eine Berechnung oder andere Arbeiten durchführen. In seltenen Fällen gibt eine Funktion keinen Wert (void-Funktion) zurück. Meistens gibt eine Funktion zumindest den Rückgabewert einer bestimmten Berechnung zurück, oder sie gibt an, ob die Ausführung der Funktion erfolgreich bzw. fehlerhaft war.

Hierzu folgt ein einfaches Beispiel für eine Funktion, die zwei Integer-Werte miteinander vergleicht und den größeren der beiden Werte zurückgibt. Sind beide Zahlen gleich, wird 0 zurückgegeben:

00  // Kapitel7/rueckgabeparameter.c
01 #include <stdio.h>

02 int intcmp(unsigned int val1, unsigned int val2) {
03 if( val1 > val2 ) {
04 return val1;
05 }
06 else if (val1 < val2) {
07 return val2;
08 }
09 return 0; // Beide sind gleich.
10 }

11 int main(void) {
12 unsigned int ival1 = 0, ival2 = 0;
13 printf("Bitte zwei Ganzzahlen eingeben: ");
14 if( scanf("%u %u", &ival1, &ival2) != 2 ) {
15 printf("Fehler beider Eingabe...\n");
16 return 1;
17 }
18 int cmp = intcmp( ival1, ival2 );
19 if(cmp != 0) {
20 printf("%d ist der hoehere Wert\n", cmp);
21 }
22 else {
23 printf("Beide Werte sind gleich\n");
24 }
25 return 0;
26 }

Listing 7.5    rueckgabeparameter.c gibt den größeren von zwei Werten oder 0 zurück, wenn diese gleich groß sind.

Anhand des Funktionskopfes der Funktionsdefinition in Zeile (02) können Sie durch das Voranstellen des Typs erkennen, dass der Rückgabewert dieser Funktion vom Typ int ist. Als Parameter erwartet diese Funktion zwei Variablen vom Typ int. Aufgerufen wird sie mit den beiden Argumenten in Zeile (18). Damit der Rückgabewert der Funktion auch irgendwo gespeichert wird, wird dieser mithilfe des Zuweisungsoperators der int-Variable cmp zugewiesen.

Welcher Wert an die Variable cmp in Zeile (18) übergeben wird, entscheidet sich in der Funktion zwischen den Zeilen (02) bis (10), wo die größere der beiden Variablen ermittelt wird. Damit am Ende auch ein Wert von der Funktion intcmp() zurückgegeben wird, müssen Sie die return-Anweisung in der Funktion dazu verwenden. Ist etwa val1 größer als val2, wird mittels return in Zeile (04) die Variable val1 aus der Funktion zurückgegeben und der Variable cmp in Zeile (18) zugewiesen. Gleiches geschieht in Zeile (07), wenn val2 größer als val1 ist. In Zeile (09) wird 0 zurückgegeben, wenn beide Werte gleich sind.

Das Programm bei der Ausführung sieht in etwa so aus:

Bitte zwei Ganzzahlen eingeben: 124 125
125 ist der hoehere Wert

Bitte zwei Ganzzahlen eingeben: 5 0
5 ist der hoehere Wert

Bitte zwei Ganzzahlen eingeben: 1 1
Beide Werte sind gleich

7.5.1    Die return-Anweisung

Wie Sie im letzten Beispiel gesehen haben, ist die return-Anweisung in Funktionen von großer Bedeutung. Mit einer return-Anweisung wird eine Funktion beendet und kehrt zum Aufrufer der Funktion zurück. Das Programm fährt direkt hinter der Zeile fort, die die Funktion aufrief. Wird die return-Anweisung hingegen in der main()-Funktion verwendet, so wie Sie diese in vielen der vorangehenden Beispiele bei einer fehlerhaften Eingabe von scanf() verwendet haben, wird das Programm beendet. Die return-Anweisung können Sie also auf unterschiedliche Arten verwenden. Bei einer Funktion mit dem Rückgabetyp void darf zwar kein Rückgabewert verwendet werden, aber Sie können trotzdem diese Funktion mit einer leeren return-Anweisung vorzeitig beenden:

return;  // Funktion mit Rückgabewert void verlassen

Es sollte aber hier nicht der Eindruck entstehen, eine Funktion mit dem Rückgabewert void müsse mit return beendet werden. Eine Funktion mit void als Rückgabewert wird auch beendet, wenn das Ende des Anweisungsblocks in den geschweiften Klammern erreicht wird.

Wenn der Rückgabetyp allerdings kein void ist, müssen Sie mit return einen Wert zurückliefern, der auch ein Ausdruck sein kann:

return ausdruck;

Ist der Typ von ausdruck unterschiedlich zum erwarteten Typ des Aufrufers, der einer Variablen zugewiesen wird, findet eine implizite Umwandlung statt, wie Sie diese von Abschnitt 4.6, »Implizite Typumwandlung«, her kennen.

Funktionsprototypen

Da Sie nun Funktionen mit Rückgabewert und formalen Parametern kennen, soll Abschnitt 7.3, »Funktionsdeklaration (Vorausdeklaration)«, etwas ergänzt werden. Dies betrifft die Art und Weise, wie Sie Funktionsprototypen für die Vorausdeklaration verwenden dürfen. Bisher kennen Sie die folgende Deklaration eines Funktionsprototyps:

int tmpval(float val1, int val2);

int main(void) {
int val = tmpval(3.23, 10);
// ...
return 0;
}

int tmpval(float val1, int val2) {
// ...
return val2;
}

Listing 7.6    Das Listing verwendet die Art der Vorausdeklaration, die bisher verwendet wurde.

Verwenden Sie den Prototyp bei der Vorausdeklaration, müssen Sie allerdings nicht zwangsläufig die Parameterbezeichner dafür nutzen. Somit können Sie die Deklaration auch wie folgt angeben:

// ohne Bezeichner auch erlaubt
int tmpval(float, int);