Sca*_*cab 2 c linux gcc function-pointers
在以下程序中&foo,*foo和foo指向相同的内存地址:
#include <stdio.h>
int foo(int arg)
{
printf("arg = %d\n", arg);
return arg;
}
int main()
{
foo(0); // ok
(*foo)(0); // ok
(&foo)(0); // ok
printf("&foo = %lx\n", (size_t)(&foo));
printf("foo = %lx\n", (size_t)(foo));
printf("*foo = %lx\n", (size_t)(*foo));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出为:
arg = 0
arg = 0
arg = 0
&foo = 55eeef54c720
foo = 55eeef54c720
*foo = 55eeef54c720
Run Code Online (Sandbox Code Playgroud)
有人可以解释吗?谢谢。
在C标准的术语中,具有函数类型的任何表达式都是函数代号。因此,当用作表达式时,函数的名称是函数指示符。
除了指定地址外,您不能使用功能指示符进行任何操作。您不能将数字添加到功能指示符,也不能将其与另一个功能指示符进行比较,依此类推。当然,您可以调用一个函数,但这实际上是通过地址而不是通过指定符来完成的,正如我稍后会解释的那样。由于除了获取其地址外,您无法使用其他任何功能,因此C会自动为您执行此操作。根据C 2018 6.3.2.1 4:
除非是运算
sizeof符或一元运算&符的操作数,否则将类型为“函数返回类型”的函数指定符转换为具有类型为“函数返回类型的指针”的表达式。
结果是:
&foo,&采用的地址foo,因此&foo也采用的地址foo。foo,功能标志被自动地转换到该函数的地址,因此foo是&foo。*foo,功能指示符自动转换为功能的地址。然后,*操作员将此转换回功能,从而产生一个功能指示符。然后,再次发生自动转换,并且功能指示符被转换回该函数的地址,因此结果*foo为&foo。当您使用function ( argument-list... )符号来调用函数时,function实际上必须是一个指向函数的指针。因此,您可以foo使用拨打电话(&foo)(arguments...)。自动转换简化了语法,因此您可以编写foo(arguments...),但是调用表达式实际上需要函数的地址,而不是函数指定符。
偶然:
printf说明符不是。size_t%zx%lx<stdint.h>,则定义用于将指针转换为整数的类型uintptr_t。这最好是将指针转换为size_t。