当按名称引用时,存储的名称在哪里?

时间:2012-07-31 07:50:02

标签: c++ c variables

例如,在我们定义变量之后:

int a=2;

之后我们可以使用“a”作为2 在我第一次学习c / c ++的时候,我认为它是理所当然的 但在我学会了“指针”的概念和变量的地址之后,我很困惑。

如果int* p=&i;,其中“i”是int。我知道p具有i的地址,所以我们可以使用* p来获取i的值。但如果我们走得更远,“p”如何被访问?看来p必须用名字引用,对吗?

到现在为止,通过地址访问变量对我来说更自然,更容易理解 但现在,当使用最简单的方法访问变量时,我对这种机制感到困惑 与int a=2;的情况一样,存储名称“a”在哪里?

为什么我们使用“a”,它相当于访问存储“a”或“2”的内存的行为?

3 个答案:

答案 0 :(得分:9)

此处a只是一个符号名称。如果它是局部变量,则不会存储在任何地方。编译器只是在编译阶段使用它,引用实际值(可以在堆栈或寄存器中),然后丢弃。

如果查看编译器生成的程序集,您会注意到a没有出现(或者可能在注释中)。编译器将适合您的变量,之后只需使用该位置(如x86上的eax寄存器)。

如果您查看了一个LLVM程序集(非常有趣),您会注意到编译器只将您的变量视为@1@2@3 ... < / p>

另一方面,如果a是一个全局变量(和一个非static),则该名称实际上将在符号表中用于引用该变量。但它反过来了 - 变量将被放置在没有名称的地方,符号表会将该名称映射到该位置,以便其他程序可以找到它。


作为旁注:如果程序是使用调试数据编译的,那么名称a将存储在那里,以便调试器可以显示它以帮助您了解正在发生的事情。

答案 1 :(得分:3)

这称为抽象。故意未指定存储a的方式和位置。编译器会为您处理它。

实际上,如果a是函数内部的局部变量,它将在调用时存储在该函数的堆栈帧中。堆栈帧的布局在编译时确定,并且在此之后不会改变。实际上,编译器将生成a的相对地址(相对于堆栈帧的开始),在实际执行该函数时将转换为绝对地址,并且起始地址堆栈框架已知。

答案 2 :(得分:2)

在编译和链接过程之后,所有符号如“a”和“p”都将转换为地址。符号仅用于按名称使用它们的函数。它就像是内存地址的标记。即使“p”保存地址“a”,编译器也会将指针“p”更改为地址。