如果您有一行代码,如
int num = 4;
这会导致以下表格吗?
VARIABLE|ADDRESS ADDRESS|VALUE
num |0001 0001 |4
如果你那么说
int* num_p = #
这会导致以下表格吗?
VARIABLE|ADDRESS ADDRESS|VALUE
num |0001 0001 |4
num_p |0002 0002 |0001
然后会说
int** num_pp = &num_p;
结果如下表所示?
VARIABLE|ADDRESS ADDRESS|VALUE
num |0001 0001 |4
num_p |0002 0002 |0001
num_pp |0003 0003 |0002
等等?如果是这样,如果初始变量不是int
而是struct
,那么同样的逻辑是否成立?
编辑:检查此问题的评论,了解地址实际上是什么样的信息,而不是0001
,0002
,0003
方案。
编辑2:This answer to this question指出变量不一定必须有地址的事实。 This answer to an earlier question也适用于此。
答案 0 :(得分:7)
是的,你用表格说明的内容大致是正确的。变量名称在编译时分配给地址。这被称为"符号表"并且类似于问题中的左侧表格。程序运行时,变量名称不再出现在可执行文件中,并且只有右侧表格中的地址。
如果是这样,如果初始变量不是int而是结构,那么同样的逻辑是否成立?
是的,struct
是一个值,因此为变量分配地址并为该地址赋值的方式相同。区别在于struct
可能比int
占用更多内存,具体取决于其成员。这会影响下一个变量的可用地址。
请注意,分配的地址将偏离某些基本内存地址。当操作系统加载可执行文件时,它会提供此基址,并且可执行文件通过将偏移量添加到基址来计算绝对内存地址。
如果您有兴趣了解其工作原理,可以更详细地学习编译器和操作系统。
答案 1 :(得分:1)
如果初始变量不是a,那么同样的逻辑也会成立 int而是结构?
结构是一个类型(如int,double,char ...)而不是变量,所以是的,你所描述的内容也适用。
答案 2 :(得分:1)
值得一提的另一点是变量不一定必须有内存地址。
编译器可能决定使用寄存器作为变量,或者地址可能在堆栈上,在这种情况下,它只是sp
(堆栈指针)的偏移量。它甚至可以混合起来。沿其范围和寿命的变量可以由编译器存储在寄存器中,然后存储在另一个寄存器中,然后在存储器中移动,然后再次加载并存储在寄存器中。或者只是将其替换为值(常量传播)或完全优化它。