Pointeurs et fonctions

Mettre des fonctions dans des variables

On peut déclarer une variable f de type int(*)(void), c'est-à-dire une fonction qui ne prend rien et renvoie un entier :

int myFunction(){ return 42; }

int (*f)(void); // là on déclare un pointeur sur une fonction qui prend pas d'argument et renvoie un entier
f = &myFunction; // mais en fait le & est optionnel car de tte façon, ça ne veut rien dire d'autres
x = (*f)()  // appel de la fonction

Pourquoi parle-t-on de pointeurs sur une fonction ?

f = &myFunction;

La segment text contient le programme lui-même. Cette zone est en lecture seule. Mais on peut pointer dessus. &myFunction est une adresse vers une case de cette zone.

Passer des fonctions en paramètre

Du coup, on peut passer des fonctions en paramètre, par exemple pour renseigner comment trier un tableau d'entiers :

#include <stdlib.h>

int cmp(const void *pA, const void *pB)
{
    /**
     * ici on fait comme si c'était des entiers à trier
    **/
    
    int* intpA = pA;
    int* intpB = pB;
    int a = *intpA;
    int b = *intpB;
    
    return a - b;
    /**
        < 0 si "a < b"
        = 0 si "a = b"
        > 0 si "a > b"
    */
}

qsort(tableau, nbElementsTableau, nbOctetsElement, cmp)

Types pour les fonctions

Déclarer une variable

Voici le type d'une fonction :

int (*) (const void*, const void*)

En C, les types donnent une position pour mettre la variable déclarée. Vous avez toujours vu TYPE NOMVARIABLE;. Là on met la variable sur le partie verte :

int (*f) (const void*, const void*);

Définir un type

typedef int (*ComparisonFunction) (const void*, const void*);

Et après on peut déclarer une variable f qui contient une fonction dont la signature est donnée par le type ComparisonFunction :

ComparisonFunction f;

ou

int cmp(const int *pA, const int *pB)
{
    return *pA - *pB;
}


qsort(tableau, nbElementsTableau, nbOctetsElement, (ComparisonFunction) cmp)