我正在学习 C 中的函数指针。我了解到函数指针存储函数起点的地址。考虑以下程序:
#include <stdio.h>
void display();
int main()
{
void (*ptr)();
ptr = &display;
(*ptr)();
return 0;
}
void display()
{
printf("hello");
}
如果void display()
的地址存储在 ptr
中, 那么 #include <stdio.h>
的地址是什么等等?
最佳答案
函数指针通常被实现为函数入口点的代码地址,但就语言而言,它只是一个可用于调用函数的不透明值(并比较 [in]equality到相同类型的其他函数指针)。它可以是程序范围或系统范围表的索引,和/或它可以包含额外信息。
该语言不提供查询语句地址的方法;就 C 标准而言,这个概念甚至不存在。
如果你想查看生成的机器代码,你可以合理地谈论为给定语句生成的代码的地址。比如你的声明
ptr = &display;
可能对应于 MOV
指令,并且该指令可能具有(机器级)地址,尽管标准语言无法让您使用该信息。 goto
语句跳转到指定的语句,它可能用一条指令实现,该指令引用该语句的第一条指令的机器地址,但标准的描述 goto
没有详细讨论它;它只描述了语义。
一些编译器,包括 gcc,有一个扩展 ( documented here ) 可以让你获取标签的地址。但这仅适用于带标签的语句。
特别是指令
#include <stdio.h>
由编译器的早期阶段处理,通常作为单独的预处理器实现。它引入了一些声明,可以被下面的代码引用。通常没有与#include
指令对应的生成代码,因此谈论它的“地址”是没有意义的。
正如 PSkocik 在评论中指出的那样,代码生成不一定是线性的;如果编译器能够重新排序以提高速度,则可能没有任何代码与给定语句关联。 (如果您使用 gcc 扩展来获取标签的地址,则编译器可能会在必要时禁止优化以确保该地址有意义。)
就标准 C 而言,即使您可以获取给定语句的地址,该语言也没有任何可以让您对其执行任何操作的结构;例如,标准的 goto
语句仅采用文字标签名称。
关于c - 程序的每一行都有自己的地址吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39858815/