Ma question est très simple.
Normalement, lorsque vous déclarez une variable, vous mettez son type avant, comme:
int a;
un pointeur de fonction peut avoir un type comme: int(*)(int,int)
, au cas où nous pointerions vers une fonction qui prend deux entiers et retourne un entier. Mais, lors de la déclaration d'un tel pointeur, son identifiant n'est pas après le type, comme:
int(*)(int,int) mypointer;
à la place, vous devez écrire l'identifiant au milieu:
int(*mypointer)(int,int);
pourquoi cela est-il ainsi? Désolé, je sais que c'est une question embarrassante facile ...
Merci à tous d'avoir répondu. COMME.
J'explique cela dans ma réponse à Pourquoi la syntaxe C pour les tableaux, les pointeurs et les fonctions a-t-elle été conçue de cette façon? , et cela se résume essentiellement à:
les auteurs du langage ont préféré rendre la syntaxe centrée sur la variable plutôt que sur le type. Autrement dit, ils voulaient qu'un programmeur regarde la déclaration et pense "si j'écris l'expression
*func(arg)
, cela donnera unint
; si j'écris*arg[N]
Je vais avoir un flotteur "plutôt que"func
doit être un pointeur vers une fonction prenant ceci et retournant que ".Le entrée C sur Wikipedia affirme que:
L'idée de Ritchie était de déclarer les identifiants dans des contextes ressemblant à leur utilisation: "la déclaration reflète l'utilisation".
... citant p122 de K & R2.
Cette structure reflète la façon dont une fonction normale est déclarée (et utilisée).
Considérons une définition de fonction normale:
int foo (int bar, int baz, int quux);
Envisagez maintenant de définir un pointeur de fonction sur une fonction de la même signature:
int (*foo) (int, int, int);
Remarquez comment les deux structures se reflètent? Qui fait *foo
beaucoup plus facile à identifier comme pointeur de fonction plutôt que comme autre chose.
Si vous traitez une fonction (pas un pointeur vers une fonction), le nom est également au milieu. Il va comme: return-type function-name "(" argument-list ")" ...
. Par exemple, dans int foo(int)
, int
est le type de retour, foo
le nom et int
la liste des arguments.
Un pointeur sur une fonction fonctionne à peu près de la même manière - type de retour, puis nom, puis liste d'arguments. Dans ce cas, nous devons ajouter un *
Pour en faire un pointeur et (puisque le *
Pour un pointeur est un préfixe) une paire de parenthèses pour lier le *
au nom au lieu du type de retour. Par exemple, int *foo(int)
signifierait une fonction nommée foo qui prend un paramètre int et renvoie un pointeur sur un int. Pour obtenir le * lié à foo
à la place, nous avons besoin de parenthèses, donnant int (*foo)(int)
.
Cela devient particulièrement moche lorsque vous avez besoin d'un tableau de pointeurs vers des fonctions. Dans un tel cas, la plupart des gens trouvent plus facile d'utiliser un typedef pour le type de pointeur, puis de créer un tableau de ce type:
typedef int (*fptr)(int);
fptr array[10];
J'avais vu à certains endroits des pointeurs de fonction déclarés comme
int (*foo) (int a, int b);
et à certains endroits, a
et b
ne sont pas mentionnés et les deux fonctionnent toujours.
donc
int (*foo) (int, int)
est également correct.
Un moyen très simple dont je me suis souvenu est comme mentionné ci-dessous:
Supposons que la fonction soit déclarée comme:
int function (int a , int b);
Step1: Mettez simplement la fonction entre parenthèses:
int (function) (int a , int b);
Étape 2: Placez un *
devant le nom de la fonction et changez le nom:
int (*funcPntr) (int a , int b);
PS: Je ne respecte pas les directives de codage appropriées pour la convention de dénomination, etc. dans cette réponse.