我创建了一段代码来测试直接变量和间接变量(指针)
#include <stdio.h>
int x = 3;
int y = 4;
int main(void)
{
int *pointer;
*pointer = x;
printf("x's address is %p, x's value is %d.\n",pointer, *pointer);
printf("y's address is %p, x's value is %d.\n",&y, y);
return 0;
}
它输出
$ ./a.out
x's address is 0x7ffee1b2d6d8, x's value is 3.
y's address is 0x10e0d301c, x's value is 4.
我可以看到x的地址存储在另一个内存块中,该内存块在编译器符号表中被称为指针作为变量,
&y怎么样,
y的地址可以由&y检索,后者将内存块放在某个地方。&y在编译器的符号表中是否有名称。
答案 0 :(得分:2)
首先,以下内容不正确:
int *pointer;
*pointer = x;
pointer
未初始化,但是您要取消引用并存储x。您可能打算分配x
的地址,即int *pointer = &x;
。
要回答是,x
和y
都最有可能使用单独的符号。您可以使用readelf
之类的工具(在GNU系统上)进行验证:
readelf -Ws a.out
将显示符号,您可以查找x
和y
。
请注意,符号和符号表等详细信息不在C标准(未指定/定义)的范围内。因此,这可能会因系统而异。
除遵守该标准外,只要遵守observed behaviour(也称为“假设规则”),标准编译器就可以生成代码,这意味着在生成的代码中不一定总是存在“变量”因为编译器通常会消除它们(或将它们放入寄存器)。
P.S:要打印地址,您需要按照格式说明符void*
的要求将其强制转换为%p
:
printf("x's address is %p, x's value is %d.\n", (void*)pointer, *pointer);
printf("y's address is %p, y's value is %d.\n", (void*)&y, y);
答案 1 :(得分:1)
在源代码中使用&y
时,编译器不需要创建新对象来存储y
的地址。
符号表中的条目实际上是x
和y
的位置。 (条目通常不是完整的地址,但通常是相对于符号所在部分的偏移量。)
因此,当使用&y
时,编译器将在生成的汇编代码中插入对y
的引用。链接器和/或加载器使用y
的地址填充此引用。
[以上内容当然不是C标准的一部分。通常只有编译器,链接器和加载器才起作用。]