next up previous contents
Nächste Seite: Komponieren in C Aufwärts: Pointer Vorherige Seite: Aufgaben   Inhalt

Zeiger auf Funktionen

Auch der Code von Funktionen liegt irgendwo im Speicher des Rechners. Es ist daher nur logisch, daß er auch eine Adresse hat. Adressen kann man in Variablen speichern, sog. Pointer. Also kann man auch die Adressen von Funktionen in Variablen speichern (Funktionspointer). Diese Funktionspointer verhalten sich genauso, wie alle anderen Pointer, mit der einen Ausnahme, daß sie nicht implizit auf einen Vektor zeigen und somit Zeigerarithmetik (z.B.: p=p+3) nicht möglich ist.

Was kann man nun mit den Objekten tun, auf die so ein Funktionspointer zeigt?

Nun, da es Funktionen sind, kann man sie aufrufen.

Und wie kriegt man die Adresse einer Funktion in einen solchen Zeiger?

Taucht der Name einer Funktion allein, also ohne folgende Klammern in einem Ausdruck auf, bedeutet er ,,Zeiger auf die Funktion mit diesem Namen`` den kann man dann ganz normal zuweisen.

Und wie sieht das nun syntaktisch aus?

Wir kennen etwa folgende Funktionsdeklaration:


int  f (int);

Dies bedeutet: f ist eine Funktion, die ein int als Parameter hat, und ein int als Resultat liefert.

Im Gegensatz dazu bedeutet:


int  (*fp) (int);

Dies bedeutet: Der Ausdruck *fp ist eine Funktion, die ein int als Parameter hat, und ein int als Resultat liefert. Da *fp die Dereferenzierung eines Pointers meint, ist also fp ein Zeiger auf eine Funktion, die ein int als Parameter hat, und ein int als Resultat liefert.

Somit können wir schreiben:


int  f (int);
int  (*fp) (int);

...
...
...
fp = f;

Wollen wir nun die Funktion aufrufen, auf die fp zeigt so können wir ganz einfach nach den Regeln der Zeigerdereferenzierung z.B. schreiben:


(*fp)(5)

Da die C-Entwickler aber notorisch schreibfaul sind, geht auch ganz einfach:


fp(5)

Mit anderen Worten: Der Funktionsaufruf einer Funktion mittels einer Zeigervariablen sieht genauso aus, wie ein gewöhnliche Funktionsaufruf. Dies ist auch konsistent mit der Aussage, daß der Name einer Funktion ihre Adresse bezeichnet.

Gehen wir nochmal zurück auf die o.g. verkettete Liste. Wir können jetzt eine Funktion schreiben, die eine gegebene Funktion (die wir als Zeiger übergeben) auf alle Datenelemente der Liste anwendet.


/* wende die Funktion func auf alle Datenelemente der Liste an */
void apply(struct list * liste, void (*func)(int) )
{
  struct item * cursor = liste -> start;
  
  while(cursor){
    func(cursor -> daten);
    cursor = cursor -> next;
  }
}
...
...
void printint(int i)
{
  printf("%d\n",i);
}
...
...
struct list l;
...
...
apply(l,printint);


next up previous contents
Nächste Seite: Komponieren in C Aufwärts: Pointer Vorherige Seite: Aufgaben   Inhalt
Thomas Neuhaus
2001-01-14