Funktionen

Eine Funktion ist wie eine Prozedur, jedoch liefert sie nach ihrer Ausführung einen sogenannten Rückgabewert zurück. Was bedeutet dies? Der Unterschied zwischen Prozedur und Funktion wird schon beim Aufruf deutlich:

Prozedur aufrufen:
void main()
{
    erklimmeHuerde();
}

Die Prozedur erklimmeHuerde arbeitet einfach nur Befehle ab.

Funktion aufrufen:
void main()
{
    int anzahl = nimmUndZaehle();
}

Die Funktion nimmUndZaehle arbeitet Befehle ab, liefert zudem aber noch eine Zahl zurück − diese kann dann z.B. in einer Variablen gespeichert werden.

1. Körner zählen

Im Folgenden siehst du, wie die Funktion nimmUndZaehle definiert wird. Die Funktion soll den Hamster die Körner auf der aktuellen Kachel aufnehmen lassen, diese dabei zählen und dann diese Anzahl zurückliefern.
int nimmUndZaehle()
{
    // Sammle und zaehle dabei (so, wie immer)
    int anzahl = 0;
    while (kornDa())
    {
        nimm();
        anzahl++;
    }
    // Hier kommt nun die Neuerung!
    return anzahl;  // Wert zurueckgeben
}

Die Zahl, die zum Schluss in der Variablen anzahl steht, wird als Rückgabewert am Ende des Funktionsrumpfes zurückgegeben (mittels des neuen return-Befehls, hier in Z. 11). Der return-Befehl muss der letzte Befehl im Funktionsrumpf sein, da mit dem Liefern des Rückgabewertes der Funktionsaufruf beendet ist.

Betrachte nun die folgenden Programmzeilen, in welchen die Funktion nimmUndZaehle aufgerufen wird. Der zurückgelieferte Wert wird an der Aufrufstelle eingesetzt und weiterverwendet (hier in Z. 4).

void main()
{
    // Hier kommt die Neuerung auf der Gegenseite (der Aufrufstelle)!
    int n = nimmUndZaehle();  // Funktion aufrufen
    schreib("Ich habe " + n + " Koerner gezaehlt!");    
}

Der Rechner macht in Z. 4 also Folgendes: Er springt zur Funktion nimmUndZaehle, arbeitet die Befehle ab, zählt z.B. „7 Körner“, und setzt dann die zurückgegebene Zahl 7 in der Aufrufstelle ein. Du kannst dir das so vorstellen, dass in dieser Situation die Zeile 4...

int n = nimmUndZaehle();

...zur Zeile...

int n = 7;
...wird.

2. Rückgabewert und Rückgabetyp

Ein weiterer Unterschied zwischen Funktionen und Prozeduren fällt in den ersten Programmzeilen direkt in Zeile 1 ins Auge: Statt void steht dort int. Bei der Definition einer Funktion wird immer der Rückgabetyp vor den Funktionsnamen geschrieben. Falls also Zahlen zurückgeliefert werden, so steht dort int; falls Wahrheitswerte zurückgeliefert werden, so steht dort boolean.

3. Vordefinierte Funktionen

Wir haben bereits Funktionen verwendet, ohne dass wir sie so genannt haben: Dies waren die sogenannten Testbefehle vornFrei, kornDa und maulLeer! Statt von Testbefehlen sprechen wir nun besser von vordefinierten Funktionen. Alle drei Funktionen haben natürlich den Rückgabetyp boolean.

4. Funktionen mehrfach aufrufen

Betrachte nun die folgende neue main-Prozedur: Hier wird nimmUndZaehle zwei Mal aufgerufen, und es werden die beiden Anzahlen addiert.

void main()
{
    int anzahl = 0;
    
    anzahl = anzahl + nimmUndZaehle(); // Zaehle auf der 1. Kachel.
    vor();
    anzahl = anzahl + nimmUndZaehle(); // Zaehle auf der 2. Kachel.

    schreib("Insgesamt " + anzahl + " Koerner!");
}

An der ersten Aufrufstelle (Z. 5) wird nun der Aufruf nimmUndZaehle() durch das Ergebnis ersetzt, z.B. durch 3, falls die aktuelle Kachel drei Körner enthält. Die anzahl beträgt dann also 0 + 3, also 3.

An der zweiten Aufrufstelle (Z. 7) wird nun der Aufruf nimmUndZaehle() durch das Ergebnis ersetzt, z.B. durch 6, falls die aktuelle Kachel drei Körner enthält. Die anzahl beträgt dann also 3 + 6, also 9.

Abschließend wird die Summe (in diesem Beispiel also 9) als Text mitgeteilt (Z. 9).

5. Mauerlücke finden

Hier ein weiteres Beispiel einer Funktion, linksFrei, welche prüft, ob die Kachel links vom Hamster frei ist. Im folgenden Beispiel soll der Hamster so lange an einer Mauer entlanglaufen, bis er eine Mauerlücke findet.

boolean linksFrei()
{
    linksUm();
    // Jetzt pruefen, ob vorne frei ist. Die vordefinierte Funktion `vornFrei` liefert
    // entweder `true` oder `false` zurueck. Dieses Ergebnis wird in der neuen Variablen
    // `frei` gespeichert.
    boolean frei = vornFrei();
    // Nun wieder nach rechts zurück drehen - schliesslich wollen wir nur herausfinden,
    // ob links frei ist, und nicht den Hamster nach links gedreht stehen lassen. 
    rechtsUm();
    // Jetzt hat der Hamster wieder die urspruengliche Blickrichtung und wir geben den
    // gespeicherten Wahrheitswert zurueck.
    return frei;
}

void main()
{
    // Laufe so lange vor, bis die Luecke erreicht ist.
    while (!linksFrei())
    {
        vor();
    }
}

// Unsere Standardprozedur...
void rechtsUm()
{
    linksUm();
    linksUm();
    linksUm();
}