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
。 归档时间: |
|
查看次数: |
72 次 |
最近记录: |