web-dev-qa-db-fra.com

Pointeur de fonction comme argument

Est-il possible de passer un pointeur de fonction comme argument à une fonction en C?

Si oui, comment déclarer et définir une fonction qui prend un pointeur de fonction comme argument?

39
inquisitive

Absolument.

void f(void (*a)()) {
    a();
}

void test() {
    printf("hello world\n");
}

int main() {
     f(&test);
     return 0;
}
67
Mehrdad Afshari

Disons que vous avez une fonction

int func(int a, float b);

Donc, le pointeur sera

int (*func_pointer)(int, float);

Donc, vous pourriez l'utiliser comme ça

  func_pointer = func;
  (*func_pointer)(1, 1.0);

  /*below also works*/
  func_pointer(1, 1.0);

Pour éviter de spécifier le type de pointeur complet chaque fois que vous en avez besoin, vous pouvez le typedef

typedef int (*FUNC_PTR)(int, float);

et que d'utiliser comme tout autre type

void executor(FUNC_PTR func)
{ 
   func(1, 1.0);
}

int silly_func(int a, float b)
{ 
  //do some stuff
}

main()
{
  FUNC_PTR ptr;
  ptr = silly_func;
  executor(ptr); 
  /* this should also wotk */
  executor(silly_func)
}

Je suggère de regarder le célèbre C faqs .

25
Michal Sznajder

C'est un bon exemple :

int sum(int a, int b)
{
   return a + b;
}

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

int div(int a, int b)
{
   return a / b;
}

int mathOp(int (*OpType)(int, int), int a, int b)
{
   return OpType(a, b);
}

int main()
{

   printf("%i,%i", mathOp(sum, 10, 12), mathOp(div, 10, 2));
   return 0;
}
The output is : '22, 5'
10
BattleTested

Comme indiqué par d'autres réponses, vous pouvez le faire comme dans

void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

Cependant, il existe un cas particulier pour déclarer un argument de type pointeur de fonction: si un argument a le type de fonction, il sera converti en pointeur sur le type de fonction, tout comme les tableaux sont convertis en pointeurs dans les listes de paramètres, donc l'ancien peut également s'écrire

void qsort(void *base, size_t nmemb, size_t size,
           int compar(const void *, const void *));

Naturellement, cela ne s'applique qu'aux paramètres, car en dehors d'une liste de paramètres, int compar(const void *, const void *); déclarerait une fonction.

2
Antti Haapala

Vérifiez qsort()

void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

Le dernier argument de la fonction est un pointeur de fonction. Lorsque vous appelez qsort() dans un de vos programmes, l'exécution "va dans la bibliothèque" et "revient dans votre propre code" grâce à l'utilisation de ce pointeur.

2
pmg