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?
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.
Déclarez votre pointeur de fonction comme ceci:
bool (*f)();
f = A;
f();
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)
.
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]))();
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();
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.
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é.
La meilleure façon de lire c'est la `` règle horaire/spirale ''
Par David Anderson
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);
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 .
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])()
{
...
}
...
}
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;
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
//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();
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!
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();