web-dev-qa-db-fra.com

Comment appeler la fonction en utilisant le pointeur de fonction?

Supposons que j'ai ces trois fonctions:

bool A();
bool B();
bool C();

Comment appeler conditionnellement une de ces fonctions à l'aide d'un pointeur de fonction et comment déclarer le pointeur de fonction?

29
Priya

Vous pouvez effectuer les opérations suivantes: Supposons que vous ayez vos fonctions A, B et C comme suit:

bool A()
{
   .....
}

bool B()
{
   .....
}

bool C()
{

 .....
}

Maintenant, à une autre fonction, dites au principal:

int main()
{
  bool (*choice) ();

  // now if there is if-else statement for making "choice" to 
  // point at a particular function then proceed as following

  if ( x == 1 )
   choice = A;

  else if ( x == 2 )
   choice = B;


  else
   choice = C;

if(choice())
 printf("Success\n");

else
 printf("Failure\n");

.........
  .........
  }

N'oubliez pas qu'il s'agit d'un exemple de pointeur de fonction. il existe plusieurs autres méthodes et pour lesquelles vous devez apprendre clairement le pointeur de fonction.

35
Abhineet

Déclarez votre pointeur de fonction comme ceci:

bool (*f)();
f = A;
f();
20
Pablo Santa Cruz

Je pense que votre question a déjà reçu une réponse plus qu'adéquate, mais il pourrait être utile de souligner explicitement que, étant donné un pointeur de fonction

void (*pf)(int foo, int bar);

les deux appels

pf(1, 0);
(*pf)(1, 0);

sont exactement équivalents à tous égards par définition. Le choix de celui à utiliser est à vous, bien que ce soit une bonne idée d'être cohérent. Pendant longtemps, j'ai préféré (*pf)(1, 0) Car il me semblait qu'il reflétait mieux le type de pf, cependant au cours des dernières années, je suis passé à pf(1, 0) .

15
Dale Hagglund

définir initialement un tableau de pointeurs de fonction qui prend un vide et renvoie un vide. en supposant que votre fonction prend un vide et retourne un vide.

typedef void (*func_ptr)(void);

maintenant, vous pouvez l'utiliser pour créer des variables de pointeur de fonction de ces fonctions. comme ci-dessous:

func_ptr array_of_fun_ptr[3];

stockez maintenant l'adresse de vos fonctions dans les trois variables.

array_of_fun_ptr[0]= &A;
array_of_fun_ptr[1]= &B;
array_of_fun_ptr[2]= &C;

vous pouvez maintenant appeler ces fonctions en utilisant des pointeurs de fonction comme ci-dessous:

some_a=(*(array_of_fun_ptr[0]))();
some_b=(*(array_of_fun_ptr[1]))();
some_c=(*(array_of_fun_ptr[2]))();
14
Vijay

Vous pouvez déclarer le pointeur de fonction comme suit:

bool (funptr*)();

Qui dit que nous déclarons un pointeur de fonction sur une fonction qui ne prend rien et renvoie un booléen.

Prochaine affectation:

funptr = A;

Pour appeler la fonction à l'aide du pointeur de fonction:

funptr();
6
codaddict
bool (*FuncPtr)()

FuncPtr = A;
FuncPtr();

Si vous souhaitez appeler une de ces fonctions de manière conditionnelle, vous devez envisager d'utiliser un tableau de pointeurs de fonction . Dans ce cas, vous auriez 3 éléments pointant vers A, B et C et vous en appelleriez un en fonction de l'index du tableau, comme funcArray0 pour A.

4
Firas Assaad
bool (*fptr)();

int main(void)
{
  ...
  ...
  printf("Enter your choice");
  scanf("%d",&a);
  switch(a)
{
  case 0:
         fptr = A;
         break;
  case 1:
         fptr = B;
         break;
  case 2:
         fptr = C;
         break;
  case 3:
          break;
}
(*fptr)();
return 0;
}

votre choix est stocké dans un; Ensuite, en conséquence, les fonctions sont affectées dans le pointeur de fonction. Enfin, selon votre choix, la même fonction est appelée pour retourner le résultat souhaité.

2
wrapperm

La meilleure façon de lire c'est la `` règle horaire/spirale ''

Par David Anderson

http://c-faq.com/decl/spiral.anderson.html

2
Vaysage

Notez que lorsque vous dites:

bool (*a)();

vous déclarez a de type "pointeur vers une fonction renvoyant bool et prenant un nombre non spécifié de paramètres". En supposant que bool est défini (vous utilisez peut-être C99 et avez inclus stdbool.h, Ou il peut s'agir d'un typedef), cela peut ou non être ce que vous voulez.

Le problème ici est qu'il n'y a aucun moyen pour le compilateur de vérifier maintenant si a est affecté à une valeur correcte. Le même problème existe avec vos déclarations de fonction. A(), B() et C() sont tous déclarés comme des fonctions "renvoyant bool et prenant un nombre non spécifié de paramètres".

Pour voir le genre de problèmes que nous pouvons rencontrer, écrivons un programme:

#include <stdio.h>

int test_zero(void)
{
    return 42;
}

static int test_one(char *data)
{
    return printf("%s\n", data);
}

int main(void)
{
    /* a is of type "pointer to function returning int
       and taking unspecified number of parameters */
    int (*a)();

    /* b is of type "pointer to function returning int
       and taking no parameters */
    int (*b)(void);

    /* This is OK */
    a = test_zero;
    printf("a: %d\n", a());

    a = test_one; /* OK, since compiler doesn't check the parameters */
    printf("a: %d\n", a()); /* oops, wrong number of args */

    /* This is OK too */
    b = test_zero;
    printf("b: %d\n", b());

    /* The compiler now does type checking, and sees that the
       assignment is wrong, so it can warn us */
    b = test_one;
    printf("b: %d\n", b()); /* Wrong again */

    return 0;
}

Quand je compile ce qui précède avec gcc, il dit:

avertissement: affectation à partir d'un type de pointeur incompatible

pour la ligne b = test_one;, ce qui est bien. Il n'y a aucun avertissement pour l'affectation correspondante à a.

Vous devez donc déclarer vos fonctions comme:

bool A(void);
bool B(void);
bool C(void);

Et puis la variable pour contenir la fonction doit être déclarée comme:

bool (*choice)(void);
2
Alok Singhal

Si vous avez besoin d'aide pour des définitions complexes, par exemple:

double (*(*pf)())[3][4];

Jetez un oeil à ma règle droite-gauche ici .

1
Jack

Approche légèrement différente:

bool A() {...}
bool B() {...}
bool C() {...}

int main(void)
{
  /**
   * Declare an array of pointers to functions returning bool
   * and initialize with A, B, and C
   */
  bool (*farr[])() = {A, B, C};
  ...
  /**
   * Call A, B, or C based on the value of i
   * (assumes i is in range of array)
   */
  if (farr[i]()) // or (*farr[i])()
  {
    ...
  }
  ...
}
1
John Bode

Vous déclarez une variable de pointeur de fonction pour la signature donnée de vos fonctions comme ceci:

bool (* fnptr)();

vous pouvez lui attribuer une de vos fonctions:

fnptr = A;

et vous pouvez l'appeler:

bool result = fnptr();

Vous pourriez envisager d'utiliser typedefs pour définir un type pour chaque signature de fonction distincte dont vous avez besoin. Cela facilitera la lecture et la maintenance du code. c'est-à-dire pour la signature de fonctions renvoyant bool sans argument, cela pourrait être:

typdef bool (* BoolFn)();

puis vous pouvez utiliser comme ceci pour déclarer la variable de pointeur de fonction pour ce type:

BoolFn fnptr;
1
x4u

Appel d'une fonction via la fonction Pointeur

float add(int , float),result;
int main()
{
 float (*fp)(int,float);
 float result;
 fp=add;
 result=add(5,10.9);      // Normal calling
 printf("%f\n\n",result);

 result=(*fp)(5,10.9);    //calling via function Pointer
 printf("%f\n\n",result);

 result=(fp)(5,10.9);    //calling via function Pointer,Indirection Operator can Be 
 omitted
 printf("%f",result);
 getch();
 }

float add(int a,float b)
{
return a+b;
}

Sortie

15.90000
15.90000
15.90000
0
Suraj Verma
//Declare the pointer and asign it to the function
bool (*pFunc)() = A;
//Call the function A
pFunc();
//Call function B
pFunc = B;
pFunc();
//Call function C
pFunc = C;
pFunc();
0
Khelben

Il a été répondu de manière plus qu'adéquate, mais vous pouvez trouver cela utile: The Function Pointer Tutorials . Il s'agit d'un traitement vraiment complet du sujet en cinq chapitres!

0
Clifford

J'utilise généralement typedef pour le faire, mais cela peut être exagéré, si vous n'avez pas à utiliser le pointeur de fonction trop souvent ..

//assuming bool is available (where I come from it is an enum)

typedef bool (*pmyfun_t)();

pmyfun_t pMyFun;

pMyFun=A; //pMyFun=&A is actually same

pMyFun();
0
Sint