此代码在注释语句一后工作正常。语句二给出了一些垃圾值,但至少它运行了。如果不将其作为函数调用,我没有得到参数中的 printf 如何给出值?
#include<stdio.h>
int main()
{
int printf = 123; // statement one
printf ("%d", printf); // statement two
return 0;
}
不带括号的函数名不返回值——它计算为函数的地址(即它是类型的函数指针size_t (*)(const char *, ...)
)。本质上,这是 CPU 在遇到调用时将在指令之间跳转的地址printf()
。
顺便说一句,如果我没记错的话,分配给函数的名称是未定义的行为,使用%d
格式说明符打印指针也是如此 - 你应该使用
printf("%p", (void *)printf);
此外,您可以声明函数指针,为其分配另一个函数的地址并调用它们就好了:
size_t (*my_printf)(const char *, ...) = printf;
my_printf("This actually called printf!\n");
printf("my_printf: %p\n", (void *)my_printf);
printf("original printf: %p\n", (void *)printf);
最后两个语句打印相同的地址。
编辑:严格来说,即使上述“解决方案”也是非标准的,因为标准不保证函数指针可以转换为数据指针类型。这意味着基本上没有办法打印函数的地址,但是,在大多数系统上,强制转换void *
显然是可行的。
在语句 2 中,当标识符printf
传递给函数时,它是一个函数指针- 一个指向函数的指针printf
-垃圾值是尝试使用printf
格式打印此地址的结果%d
::您应该看到编译器警告使用打印指针时%d
。