C function pointer syntax
Solution 1:
I explain this in my answer to Why was the C syntax for arrays, pointers, and functions designed this way?, and it basically comes down to:
the language authors preferred to make the syntax variable-centric rather than type-centric. That is, they wanted a programmer to look at the declaration and think "if I write the expression
*func(arg)
, that'll result in anint
; if I write*arg[N]
I'll have a float" rather than "func
must be a pointer to a function taking this and returning that".The C entry on Wikipedia claims that:
Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".
...citing p122 of K&R2.
Solution 2:
This structure reflects how a normal function is declared (and used).
Consider a normal function definition:
int foo (int bar, int baz, int quux);
Now consider defining a function pointer to a function of the same signature:
int (*foo) (int, int, int);
Notice how the two structures mirror each other? That makes *foo
much easier to identify as a function pointer rather than as something else.
Solution 3:
If you're dealing with a function (not a pointer to one), the name is in the middle too. It goes like: return-type function-name "(" argument-list ")" ...
. For example, in int foo(int)
, int
is the return type, foo
the name and int
the argument list.
A pointer to a function works pretty much the same way -- return type, then name, then argument list. In this case, we have to add a *
to make it a pointer, and (since the *
for a pointer is prefix) a pair of parentheses to bind the *
to the name instead of the return type. For example, int *foo(int)
would mean a function named foo that takes an int parameter and returns a pointer to an int. To get the * bound to foo
instead, we need parentheses, giving int (*foo)(int)
.
This gets particularly ugly when you need an array of pointers to functions. In such a case, most people find it easiest to use a typedef for the pointer type, then create an array of that type:
typedef int (*fptr)(int);
fptr array[10];
Solution 4:
I had seen at some places function pointers declared as
int (*foo) (int a, int b);
and at some places a
and b
are not mentioned and both still works.
so
int (*foo) (int, int)
is also correct.
A very simple way that I found to remember is as mentioned below:
Suppose function is declared as:
int function (int a , int b);
Step1: Simply put function in parentheses:
int (function) (int a , int b);
Step2: Place a *
in front of function name and change the name:
int (*funcPntr) (int a , int b);
PS: I am not following proper coding guidelines for naming convention etc. in this answer.