问题
According to the GNU C manual, functions can be called using function pointers like so:
func (j); /* (*func) (j); would be equivalent. */
So my reasoning here is: func itself is a pointer to the func(int) function. When you call func(j), you are implicitly accessing the value of the pointer func (you are moving to the memory location where func is), in the same way as when you have a pointer to an integer, for example, and you access the value stored in that position of the memory using *. That would be consistent with the fact that you can call that same function using (*func)(j).
In fact, in cprogramming.com, they say you can have a pointer to a pointer of a function. So I am therefore guessing they work like any other kind of pointers.
But if that's the case, why is it that this code works?
#include <stdlib.h>
#include <stdio.h>
void a(int n) {
printf("%d\n", num);
}
int main() {
int x = 5;
void (*func)(int); // Declare a pointer to a function
func = &a; // Pointer to a pointer to a function
(*func)(x); // Calls the function (why?)
func = a; // Pointer to a function
(*func)(x); // Calls the function (makes sense)
}
Moreover, if you call:
printf("%s\n", (&a == a) ? "True" : "False");
It prints True!
I am sure that &foo is not the same as &&foo, for example, so why does it seem to be the case that func is the same as &func?
回答1:
N1570 6.3.2.1 Lvalues, arrays, and function designators says:
4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator,65) or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
Here a and *func are function designators because they have function type. a in &a is not converted to a pointer because it is the operand of the unary & operator and the pointer to the function is retrieved by the & operator.
On the other hand, a in func = a; is converted to the pointer to the function according to this rule.
Therefore a and &a in this code are equivalent.
Also func in func(x); is converted to the pointer according to this rule.
(*func)(x); is:
funcis converted to the pointer according to this rule- The pointer is dereferenced by
*in*func *funcis converted to the pointer according to this rule
Thus (*func)(x); is equivalent to func(x);.
回答2:
A function designator used in expressions is implicitly converted to pointer to the function.
So for example you could call your function like
( **********a )( 5 );
That is in this expression *a the function designator a is converted to pointer to the function. Applying the dereference operator * you again get a function designator that in turn is converted to pointer to the function in the expression **a. And so on.
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator65) or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
So in this assignment
func = &a; // Pointer to a pointer to a function
there is used the operator & (see the quote from the C Standard) that means that the function designator a is not converted to function pointer in this expression. And you do not have pointer to a function pointer as you wrote in the comment to the statement above.
回答3:
From the very documentation you've provided:
5.6 Calling Functions Through Function Pointers You can also call a function identified by a pointer. The indirection operator * is optional when doing this.
#include <stdio.h> void foo (int i) { printf ("foo %d!\n", i); } void bar (int i) { printf ("%d bar!\n", i); } void message (void (*func)(int), int times) { int j; for (j=0; j<times; ++j) func (j); /* (*func) (j); would be equivalent. */ } void example (int want_foo) { void (*pf)(int) = &bar; /* The & is optional. */ if (want_foo) pf = foo; message (pf, 5); }
So, The indirection operator * is optional when doing this. and /* The & is optional. */ comments says it all. They're optional. Why they are optional is explained by @MikeCat and @Vlad from Moscow
来源:https://stackoverflow.com/questions/64718604/why-does-it-seem-that-func-is-the-same-as-func-in-c