为什么 func 看起来和 C 中的 &func 一样?
Why does it seem that func is the same as &func in C?
根据 GNU C manual,可以使用函数指针调用函数,如下所示:
func (j); /* (*func) (j); would be equivalent. */
所以我的推理是:func
本身是指向 func(int)
函数的指针。当你调用 func(j)
时,你正在隐式访问指针 func
的值(你正在移动到 func
所在的内存位置),就像你有一个指针时一样例如,转换为一个整数,您可以使用 *
访问存储在内存该位置的值。这与您可以使用 (*func)(j)
.
调用相同函数的事实是一致的
事实上,在 cprogramming.com 中,他们说你可以有一个 指向函数指针的指针 。因此,我猜测它们的工作方式与任何其他类型的指针一样。
但如果是这样,为什么这段代码有效?
#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)
}
此外,如果您调用:
printf("%s\n", (&a == a) ? "True" : "False");
它打印 True
!
我确定&foo
与&&foo
不一样,所以为什么func
与 &func
?
相同
表达式中使用的函数指示符被隐式转换为指向函数的指针。
例如,您可以像这样调用您的函数
( **********a )( 5 );
即在此表达式 *a
中,函数指示符 a
被转换为指向函数的指针。应用取消引用运算符 *
,您将再次获得一个函数指示符,该指示符又被转换为指向表达式 **a
中的函数的指针。等等。
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
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’’.
所以在这个作业中
func = &a; // Pointer to a pointer to a function
使用了运算符 &
(请参阅 C 标准中的引文),这意味着函数指示符 a
不会在此表达式中转换为函数指针。而且你没有指向函数指针的指针,正如你在上面语句的注释中所写的那样。
N1570 6.3.2.1 左值、数组和函数指示符说:
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’’.
此处 a
和 *func
是 函数指示符 因为它们具有函数类型。 &a
中的 a
未转换为指针,因为它是一元 &
运算符的操作数,并且指向函数的指针由 &
运算符检索。
另一方面,func = a;
中的a
根据这个规则转换为指向函数的指针。
因此,此代码中的 a
和 &a
是等价的。
另外func(x);
中的func
也是按照这个规则转换为指针的。
(*func)(x);
是:
func
按照这个规则转换为指针
- 指针在
*func
中被 *
取消引用
*func
按照这个规则转换为指针
因此 (*func)(x);
等价于 func(x);
.
根据您提供的文档:
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);
}
所以,The indirection operator * is optional when doing this.
和 /* The & is optional. */
评论说明了一切。它们 可选 。来自莫斯科的@MikeCat 和@Vlad 解释了为什么它们是可选的
根据 GNU C manual,可以使用函数指针调用函数,如下所示:
func (j); /* (*func) (j); would be equivalent. */
所以我的推理是:func
本身是指向 func(int)
函数的指针。当你调用 func(j)
时,你正在隐式访问指针 func
的值(你正在移动到 func
所在的内存位置),就像你有一个指针时一样例如,转换为一个整数,您可以使用 *
访问存储在内存该位置的值。这与您可以使用 (*func)(j)
.
事实上,在 cprogramming.com 中,他们说你可以有一个 指向函数指针的指针 。因此,我猜测它们的工作方式与任何其他类型的指针一样。
但如果是这样,为什么这段代码有效?
#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)
}
此外,如果您调用:
printf("%s\n", (&a == a) ? "True" : "False");
它打印 True
!
我确定&foo
与&&foo
不一样,所以为什么func
与 &func
?
表达式中使用的函数指示符被隐式转换为指向函数的指针。
例如,您可以像这样调用您的函数
( **********a )( 5 );
即在此表达式 *a
中,函数指示符 a
被转换为指向函数的指针。应用取消引用运算符 *
,您将再次获得一个函数指示符,该指示符又被转换为指向表达式 **a
中的函数的指针。等等。
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
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’’.
所以在这个作业中
func = &a; // Pointer to a pointer to a function
使用了运算符 &
(请参阅 C 标准中的引文),这意味着函数指示符 a
不会在此表达式中转换为函数指针。而且你没有指向函数指针的指针,正如你在上面语句的注释中所写的那样。
N1570 6.3.2.1 左值、数组和函数指示符说:
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’’.
此处 a
和 *func
是 函数指示符 因为它们具有函数类型。 &a
中的 a
未转换为指针,因为它是一元 &
运算符的操作数,并且指向函数的指针由 &
运算符检索。
另一方面,func = a;
中的a
根据这个规则转换为指向函数的指针。
因此,此代码中的 a
和 &a
是等价的。
另外func(x);
中的func
也是按照这个规则转换为指针的。
(*func)(x);
是:
func
按照这个规则转换为指针- 指针在
*func
中被 *func
按照这个规则转换为指针
*
取消引用
因此 (*func)(x);
等价于 func(x);
.
根据您提供的文档:
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); }
所以,The indirection operator * is optional when doing this.
和 /* The & is optional. */
评论说明了一切。它们 可选 。来自莫斯科的@MikeCat 和@Vlad 解释了为什么它们是可选的