Funktions-Deklaration

In C und C++ wird eine Funktion deklariert, indem man ihr einen Rückgabetyp, ein Symbol und eine Auflistung von Parametern in runden Klammern () gibt. Durch die Deklaration der Funktion kann sie an anderer Stelle mittels des Funktionsaufruf-Operators aufgerufen werden.

float area(float r);

Siehe auch Funktions-Definition, Funktionsaufruf-Operator

Details

Eine Funktions-Deklaration wird durch ein Semikolon ; abgeschlossen. Die tatsächliche Ausprogrammierung der Funktion verwendet anstelle des Semikolons geschweifte Klammern {}, was bei der Funktions-Definition nachgelesen werden kann.

Der Rückgabetyp in Verbindung mit der Parameterliste wird als Funktionstyp oder Signatur bezeichnet. Ein eindeutiger Funktionstyp besteht somit stets aus dem Rückgabetyp UND der Parameterliste. Weitere Erklärungen dazu findet man bei den Funktions-Pointer.

Rückgabetyp

Der Rückgabetyp einer Funktion steht an erster Stelle der Funktionsdeklaration und legt den Typ des Wertes fest, welcher durch die Funktion zurückgegeben wird.

float area(float r);

Gibt die Funktion keinen Wert zurück, so handelt es sich um eine sogenannte Prozedur. Eine Prozedur unterscheidet sich von einer Funktion somit einzig darin, dass eine Funktion einen Wert zurück gibt, eine Prozedur jedoch nicht. In C und C++ wird deswegen der Begriff Prozedur nicht verwendet, sondern als Funktionen mit dem Rückgabetyp void angegeben, was für den Rückgabewert zu interpretieren ist als: ungültig, zu ignorieren.

void print_addition(int a, int b);

Versucht man bei einer Funktion mit Rückgabetyp void trotzdem, den Wert im Programm zu verwenden, so wird der Compiler einen Fehler wie etwa den folgenden ausgeben: void value not ignored as it ought to be. Versucht man, in einer solchen Funktion trotz der Angabe, dass kein Wert zurückgegeben werden soll, einen Wert zurückzugeben, wird eine Warnung wie die folgende ausgegeben: return with a value, in function returning void.

Symbol

Der Programmierer kann einer Funktion ein Symbol zuweisen, oder anders gesagt ihr einen Namen geben. Bei der Funktionsdeklaration wird der Name vor den Klammern der Parameterliste angegeben:

float area(float r);

Parameterliste

Jede Funktion kann eine beliebige Anzahl an Parametern deklarieren, welche die bei einem Funktionsaufruf übergebenen Argumente speichern. Die einzelnen Parameter stehen später innerhalb der Funktion als normale Variablen zur Verfügung. Parameter werden als sogenannte Parameterliste in runden Klammern () nach dem Funktionsnamen angegeben.

int   do_nothing1    ();
int   do_nothing2    (void);
float area           (float r);
void  print_addition (int a, int b);
int   printf         (const char *restrict format, ...);

Es sei zu beachten, dass andere Quellen die Parameterliste als Argumentenliste bezeichnen. Hier auf ManderC wird bei der Signatur einer Funktion stets von einer Parameterliste gesprochen, da es sich um die Deklaration der innerhalb der Funktion verfügbaren Variablen handelt. Für weitere Informationen über den Unterschied zwischen Parameter und Argumente sowie die verschiedenen Übergabemechanismen wird auf die Argumente- und Parameter-Seite verwiesesn.

Die einzelnen Parameter sind grundsätzlich Variablendeklarationen (mit Typ und Name) und werden mittels Komma , voneinander getrennt. Eine Parameterliste mit mindestens einem Parameter kann auch mittels den Auslassungspunkten ... erweitert werden, was eine beliebige zusätzliche Anzahl an zu übergebender Parameter erlaubt.

Wenn eine leere Parameterliste angegeben wird, bedeutet dies unter C++, dass die Funktion keine Parameter erwartet. In C bedeutet eine leere Parameterliste, dass nicht spezifiziert ist, wieviele Parameter erwartet sind. Eine Funktion, die explizit keine Parameter annehmen soll, kann (in C und C++) mittels dem void-Keyword angegeben werden.

Wenn in C bei der Funktionsdeklaration die ganze Parameterliste leer ist (auch kein void), so wird das Symbol lediglich als eine Funktion deklariert, jedoch nicht spezifiziert, wieviele Parameter sie tatsächlich annimmt. Erst ab Auftreten der Definition der Funktion wird die Parameterliste festgelegt. Dies kann bei unsorgfältiger Programmierung zu Fehlern führen. Im folgenden Beispiel wird die Funktion ohne Parameterliste deklariert und kann somit mit beliebigen Argumenten aufgerufen werden, solange sie noch nicht definiert wurde. Dadurch entstehen fehlerhafte Ausgaben. In C++ funktioniert dies jedoch nicht mehr.






1234
and now...
8094
#include <stdio.h>

void printInt();

int main(){
  printInt(1234);
  printf("and now...\n");
  printInt();
  return 0;
}

void printInt(int x){
  printf("%d\n", x);
}

Old-Style Parameter

Es gibt nebst der oben aufgeführten, heute üblichen Parameterlisten-Deklaration auch noch eine alte Methode, welche allgemein als old-style bezeichnet und heutzutags kaum mehr verwendet wird. Bei der old-style-Variante werden die Symbole innerhalb der runden Klammern ohne Typ deklariert. Dadurch werden die zu übergebenden Typen nach aussen hin versteckt, die Deklaration kann somit nicht als Prototyp verwendet werden.

Die Typ-Zuordnung steht als eigenständige Deklaration nach den runden Klammern oder wird, wenn die Typzuordnung gänzlich fehlt, standardmässig als int angenommen.











30
#include <stdio.h>

int multiply(a, b)
int a;
int b;
{
  return a*b;
}

int main(){
  printf("%i\n", multiply(5, 6));
  return 0;
}

C-Compiler erlauben diese Syntax auch heute noch, da insbesondere in der Systemprogrammierung diese Syntax immer noch teilweise verwendet wird. Moderne C++ Compiler erlauben diesen Style jedoch nicht mehr.

Zusatzeigenschaften in C++

Während in C innerhalb eines Bereiches jeder Name eindeutig sein muss, kann man in C++ mehrere Funktionen mit demselben Namen deklarieren, die jedoch eine unterscheidbare Parameterliste aufweisen müssen. Mehr darüber ist nachzulesen bei der Funktions-Überladung.

In C++ können Funktionen als Teil einer Klasse deklariert werden, was dann nicht mehr als Funktion, sondern als Methode bezeichnet wird. Solche Methoden können die Objekte, denen sie angehören, grundsätzlich beliebig verändern, es sei denn, die Methode ist mittels einem angehängten const-Keyword deklariert. Einer solchen Methode ist es nicht erlaubt, die Felder des zugehörigen Objektes zu ändern. Die zusätzliche Deklaration mittels des const-Keyword gehört zum eindeutigen Funktionstyp.

class Person{
  float size;
  float weight;
  float bmi() const {return weight / (size * size);}
};

In C++ können Funktionen zudem gekennzeichnet werden, dass sie nur bestimmte Ausnahmebehandlungen zulassen. Dies wird mittels einer angehängten throw-Deklaration geschrieben. Die genaue Bedeutung und Verwendung dieser Deklaration findet man beim throw-Keyword. Anmerkung: Diese Angabe gehört NICHT zum eindeutigen Funktionstyp.

float area(float r) throw(int);

Die Verwendung beider Zusatzangaben const und throw erwartet die const-Angabe zuerst und danach die throw-Angabe abgetrennt mit einem Leerzeichen.

float area(float side) const throw(float);

Standard-Werte für Parameter

In C++ können die Parameter in Funktionsdeklarationen mit einem Standardwert belegt werden. Dadurch ist es möglich, dass bei einem Funktionsaufruf einige Werte weggelassen werden können, worauf der Compiler automatisch den Funktionsaufruf mit den Standardwerten erweitert.

















5
11
-1
#include <cstdio>
#include <cstring>

int getTokenSize( const char* str,
                  char delimiter = ' ',
                  int maxlen = -1){
  int i=0;
  if(maxlen == -1){maxlen = strlen(str);}
  for(i=0; i<maxlen; i++){
    if(str[i]==delimiter){return i;}
  }
  return -1;
}

int main(){
  const char* string = "Hello World!";
  printf("%i\n", getTokenSize(string));
  printf("%i\n", getTokenSize(string, '!'));
  printf("%i\n", getTokenSize(string, '!', 10));
  return 0;
}

Es ist möglich, jedem Parameter einen Standardwert zuzuweisen, allerdings müssen sämtliche Parameter, die nach dem ersten Standard-Parameter deklariert werden, ebenfalls einen Standardwert aufweisen. Wenn bei einem Parameter kein Standardwert angegeben wird, welcher sich jedoch nach einem Parameter mit Standardwert befindet, so meldet der Compiler einen Fehler wie Default argument missing for parameter ....

Es ist zu beachten, dass es sich bei der Angabe eines Standard-Wertes um eine Initialisierung handelt, und nicht um eine Zuweisung.