pointeur de fonction

La déclaration suivante est une déclaration de pointeur de fonction renvoyant comme résultat un entier et recevant en paramètres deux entiers :

int (* point_fonction) (int, int) ;

Attention, à l’intention des parenthèses. La déclaration suivante correspond à celle d’une fonction rendant un pointeur sur un entier :

int * point_fonction (int, int) ;

Attention, il y a deux notations en C pour affecter l’adresse d’une fonction à un pointeur

  • point_fonction = f ; Un nom de fonction dans une expression est automatiquement converti en un pointeur sur la fonction
  • point_fonction = &f ; C’est la notation habituelle pour accéder à l’adresse d’un objet. Cette notation pour les fonctions n’était pas autorisée en C.

Le paramètres formel d’une fonction peut être un pointeur sur une fonction (mais pas une fonction).

Attention à ne pas oublier les parenthèses lors d'une appel à une fonction sans paramètre.

f; est correct c'est un pointeur qui a une valeur. C'est aussi une instruction expression qui n'a aucun effet.

De même l'affectation de fonction f1 = f2 ; n'a pas des sens. La partie droite de l'affectation est transformée en pointeur sur la fonction.

Quel usage des pointeurs sur fonctions ?

Dans nombres de langages, il n’y a pas de pointeurs de fonctions. Certain des usages correspondent au concept de généricité du langage ADA (paramètres générique de type fonction). De plus façon plus élaborée, les pointeurs de fonctions peuvent servir à implémenter en C le mécanisme d’héritage entre classes et de liaison dynamique des langages objets (Java, C++, …).

Un exemple proche du mécanisme de généricité d’Ada.

On peut par exemple écrire une fonction de tri d’un tableau ayant comme pointeur une fonction de comparaison de deux éléments. C’est au moment de l’appel de la fonction de tri qu’un pointeur sur la fonction de comparaison appropriée est passé en paramètre. On pourra ainsi utiliser une unique fonction de tri pour ordonner un tableau d’individus, soit par ordre alphabétique de leur nom (ascendant ou descendant, soit par leur résultat à un concours.

Voici un programme plus simple illustrant cet usage. Le programme lit deux nombres et affiche leur somme ou leur différence en utilisant une fois une fonction plus, et une fois une fonction moins.

int plus (int a, int b) {

return a+b ;

}

int moins (int a, int b) {

return a-b ;

}

int plus_ou_moins (int a, int b, int (*operation) (int, int) ) {

return operation (a, b) ;

}

void main () {

int i, j ;

printf (« Entrez deux valeurs entières \n »} ;

scanf («%d %d », &i, &j) ;

printf (« La somme de %d et %d est %d \n », i, j, plus_ou_moins (i, j, plus)) ;

printf (« La difference de %d et %d est %d \n », i, j, plus_ou_moins (i, j, moins)) ;

}

Nous donnerons dans les exercices des exemples correspondant à l’implémentation de la liaison dynamique et de l’héritage.

» Glossaire du langage C