Pointeurs de fonctions.

Pointeurs de fonction

Voir version :

Pas de dépendances

Télécharger :

#include <stdio.h>

typedef void (*fonc)(int);

void test(int a)
{
    printf("forme premiere, nombre : %d\n",a);
}

void retest(int a)
{
    printf("forme seconde, nombre : %d\n",a);
}

void mafonction(fonc f)
{
    int i;
    for(i=0;i<5;i++)
        f(i);
}

int main()
{
    mafonction(test);
    mafonction(retest);
    system("PAUSE");
    return 0;
}



Commentaires


Petit tuto sur les pointeurs de fonctions
Certaines personnes n'aiment pas du tout.

Moi je trouve ça rigolo : imaginez, tout simplement que vous puissiez faire un pointeur p, que vous le faites pointer sur
test, ou sur retest, et en fonction de cela, vous lui dites d'appeler la fonction pointée par p...

Prenons l'exemple :

  je déclare un type, avec typedef :

  typedef void (*fonc)(int);

  ce type est déclaré bizarrement par rapport aux autres, mais ça veut dire, que vous déclarez fonc, qui pointera vers une 
  fonction de type :

	void X(int)

  si vous voulez déclarer un type "plouf" qui pointe vers une fonction de type :

	double X(int,char*,float)
	
vous définissez cela ainsi :

	typedef double (*plouf)(int,char*,float);

tout simplement.

Apres la déclaration, ça s'utilise et ça se passe en parametre comme un autre type :

la fonction mafonction prend d'ailleurs un type "fonc" qu'elle appelle f.
Regardez les appels :
On dit :

  mafonction(test);

c'est équivalent a :

  fonc f = test;
  mafonction(f);

(comme un autre type !)

donc "mafonction" va donc recevoir un pointeur de fonction qui s'appelle f

Comment utiliser ce pointeur ?
simplement avec :

f(); a l'intérieur de "mafonction"

evidemment, si fonc était du type  
	
	  double X(int,float);

on aurait pu mettre dans "mafonction"

double d = f(3,2.1);

Et c'est ainsi que ça fonctionne. Et évidemment, les fonctions mentionnées "test" et "retest" sont bien du type de fonc....



Applications :

Imaginons que fassiez une fonction :

"ExploreArbre"

pour, donc, explorer un arbre. 
Disons, simplement, que chaque noeud de cet arbre contient un int.
  
Que faites vous si vous arrivez a un noeud ? 
Vous voulez écrire la valeur du int qu'il y a à ce noeud ? 
et bien 
- soit vous faites un cout ou printf de façon hard dans la fonction "ExploreArbre"
- soit vous appelez un pointeur de fonction (avec la référence du noeud en parametre), 
qui pointe vers une fonction qui fera le cout...

Et maintenant, vous voulez parcourir l'arbre, mais cette fois ci, vous ne voulez pas afficher le int, mais le remettre à 0 :
bref, vous voulez remettre les valeurs de tout l'arbre a 0...
- sans pointeur de fonction, vous faites un copier/coller de ExploreArbre, et vous remplacez le cout << element par un element=0;
- avec pointeur de fonction, vous appelez simplement ExploreArbre avec comme parametre, un pointeur de fonction différent, qui,
au lieu de pointer sur la fonction qui affiche l'élément, pointe sur la fonction qui met l'élément a 0...

Voila :)

Il y a plein d'autres applications...
Le polymorphisme, en C++, s'inspire de cela : en effet, quand vous lancez une fonction, soit vous lancez celle du morphe 1, soit
celle du morphe 2...
Les foncteurs des STL sont également ce genre de choses...

Les pointeurs de fonctions sont un élément orienté C.
qsort s'appuie sur les pointeurs de fonctions