7 Funktionen erstellen
In diesem Kapitel lernen Sie, wie Sie in C eigene Funktionen definieren können. In der Praxis werden Sie nämlich die komplette Programmausführung oft nicht in einem einzigen Anweisungsblock zusammenfassen, sondern eine Problemlösung in viele kleine Teilprobleme zerlegen und mithilfe von mehreren Unterprogrammen lösen. Jedoch ist der Begriff Unterprogramm ein recht veralteter Begriff, den es schon zu BASIC-Zeiten gab, als man noch mit GOSUB an eine andere Stelle im Programm sprang und mit RETURN wieder zur ursprünglichen Stelle zurückkehrte.
Inzwischen wird jedoch der Begriff Unterprogramm nicht mehr verwendet, und deshalb wollen wir es hier auch nicht tun. Moderne Funktionen, wie sie es in C gibt, bieten nämlich viel mehr. Sie können z. B. Werte an eine Funktion übergeben und sich sogar von dieser Werte zurückgeben lassen. Ein Beispiel aus der Standardbibliothek math.h ist z. B. die Cosinus-Funktion y=cos(x), die den Cosinus von x als Wert vom Typ double zurückgibt. Selbstverständlich wird die hier übergebene Variable x selbst nicht verändert.
Außerdem bieten Funktionen einen Schutz der innerhalb der Funktion verwendeten Variablen: Die Variablen, die Sie innerhalb einer Funktion deklarieren, sind nach außen hin nicht sichtbar, und Sie haben so einen guten Schutz vor dem versehentlichen Überscheiben. Deshalb (eben wegen der hohen Sicherheit) werden die Anweisungen eines C-Programms grundsätzlich in Funktionen zusammengefasst. Die Funktion, die beim Start eines Programmes immer als Erstes angesprochen wird, ist die main()-Funktion. Diese haben Sie bisher immer verwendet. Die main()-Funktion bildet die Hauptfunktion, und von dort aus werden alle anderen Funktionen aufgerufen und gestartet. Selbstverständlich haben Sie bereits mit Funktionen gearbeitet; diese wurden jedoch in externen Header-Dateien deklariert, und nicht von Ihnen. Eine von diesen Funktionen ist z. B. printf(). Dass es sich hier wirklich um eine Funktion handelt, erkennen Sie daran, dass Sie printf() in runden Klammern den Text übergeben müssen, und dass printf() dann diesen Parameter genannten Text entgegennimmt und mit diesem etwas tut (nämlich diesen Text auf dem Bildschirm auszugeben). Wie Sie eigene Funktionen erstellen, die sogar Werte zurückgeben können, erfahren Sie in diesem Kapitel.
7.1 Funktionen definieren
Zunächst die grundlegende Syntax einer Funktion:
[Spezifizierer] <Datentyp> <Funktionsname>( [Parameter] ) {
// Anweisung(en)
}
Im Funktionskopf können folgende Bestandteile verwendet werden:
-
Spezifizierer
Ein Speicherklassen-Spezifizierer ist optional und wird gesondert in den entsprechenden Stellen des Buches beschrieben (beispielsweise in Abschnitt 7.6, »Exkurs: Funktionen bei der Ausführung«). Speicherklassen-Spezifizierer treten oft bei der Hardware-Programmierung auf, bei der sich ein Variablenwert z. B. auch ohne Zugriff Ihres C-Programms ändern kann, weil z. B. der USB-Controller darauf zugreifen darf. In diesem Fall müssten Sie z. B. das Schlüsselwort volatile noch vor der Typangabe angeben. Als Einsteiger werden Sie also kaum in Berührung mit Speicherklassen-Spezifizierern kommen. -
Datentyp
Hiermit wird der Typ des Rückgabewertes spezifiziert. Sie können beliebige Datentypen verwenden oder void, wenn eine Funktion keinen Rückgabewert zurückgibt. -
Funktionsname
Dies muss ein eindeutiger Funktionsname sein, mit dem Sie diese Funktion von einer anderen Programmstelle aus aufrufen können. Für den Namen gelten dieselben Regeln wie schon bei den Variablennamen (siehe Abschnitt 2.4.1, »Bezeichner«). Außerdem sollten Sie keine Funktionsnamen der Standardbibliothek, wie z. B: printf() verwenden, weil diese unter Umständen (vor allem von C++-Compilern) kommentarlos überschrieben werden. -
Parameter
Auch die Parameter einer Funktion sind optional, die Klammerung hinter dem Funktionsnamen allerdings nicht. Sie muss immer vorhanden sein. Wenn Sie keine Parameter verwenden, sollten Sie das Schlüsselwort void einsetzen. Sie müssen void nicht zwingend angeben, sollten dies aber der Übersicht halber tun. Ansonsten werden die einzelnen Parameter mit ihrem Datentyp und dem Bezeichner für die Verwendung innerhalb der Funktion spezifiziert und, wenn Sie mehr als einen Parameter verwenden, mit einem Komma voneinander getrennt. -
Anweisungsblock mit Anweisungen
Ebenso wie die main()-Funktion enthält auch eine Funktion einen Anweisungsblock, in dem die Funktionsanweisungen und lokalen Deklarationen zusammengefasst werden.