提问人:Bemin Dawoud 提问时间:10/23/2023 最后编辑:CiaPanBemin Dawoud 更新时间:10/23/2023 访问量:94
为什么变量的地址在这里发生变化?
Why is the address of the variable changing here?
问:
我正在尝试使用指针来更好地掌握它,我在这里遇到了这种情况: 我声明了一个变量 var 和两个指针。我正在打印 var 的地址以将其与两个指针进行比较,但即使语句相同,它也在两个值之间不断变化?
这是它第一次给出 var 的地址:0061FF1C
我使用的代码:
#include <stdio.h>
int main () {
int var;
int *ptr;
int **pptr;
var = 3000;
ptr = &var;
pptr = &ptr;
printf("Address of var = %p\n", &var );
printf("Value available at ptr = %p\n", ptr ); // should be equal to address of Var
printf("Address of ptr = %p\n", &ptr ); // should be equal to address of ptr
printf("value available at pptr = %p\n", pptr); // should be equal to address of ptr
printf("address of pptr = %p\n", &pptr ); // should be equal to address of pptr
return 0;
}
输出:
Address of var = 0061FF1C
Value available at ptr = 0061FF1C
Address of ptr = 0061FF18
value available at pptr = 0061FF18
address of pptr = 0061FF14
这是它第二次给出 var 的地址:
我使用的代码:0061FF18
#include <stdio.h>
int main () {
int var;
int *ptr;
int **pptr;
var = 3000;
ptr = &var;
pptr = &ptr;
printf("Address of var = %p\n", &var );
printf("Value available at ptr = %p\n", ptr ); // should be equal to address of Var
printf("value available at pptr = %p\n", pptr); // should be equal to address of ptr
return 0;
}
输出:
Address of var = 0061FF18
Value available at ptr = 0061FF18
value available at pptr = 0061FF14
我期望 var 的值每次都相同 为什么会改变?
答:
在不打印的程序中,该对象不需要有地址,因此编译器能够通过不实际将程序存储在内存中来优化程序。该程序可以将 的值保存在处理器寄存器中和/或根据需要“动态”创建它。由于没有为其分配内存,因此会更改其他对象(如 )所在的位置。&pptr
pptr
var
编译器可以使用复杂的算法为对象分配内存。然而,在这个有限的问题中,我们可以考虑一个简单化的观点。从本质上讲,编译器准备有关需要存储在堆栈上的对象的信息,然后在堆栈帧中为这些对象分配位置,结果是它为其分配位置的第一个对象将位于地址 0061FF14 16,下一个对象位于 0061FF1816,下一个对象位于 0061FF1C16。(堆栈帧中还有其他东西,这就是为什么我们在这种情况下看到的第一个对象从 0061FF14 16 开始,而不是从 0061FF1016 开始。main
在程序的第一个版本中,程序打印 、 和 的地址。因此,这些对象必须具有地址。无论出于何种原因,编译器都会按顺序处理它们,并分别为它们提供地址 0061FF14 16、0061FF1816 和 0061FF1C16。var
ptr
pptr
pptr
ptr
var
在程序的第二个版本中,程序打印 和 的地址(后者通过分配 然后打印 )。它从不使用 的地址,因此不需要有实际地址;编译器能够在不放入内存的情况下使程序工作。因此,对于此程序,编译器为 和 分配内存,它们最终位于地址 0061FF14 16 和 0061FF1816。因此,的地址与程序的第一个版本相差四个字节。var
ptr
&ptr
pptr
pptr
pptr
pptr
pptr
var
ptr
ptr
评论
// should be equal to address of ptr
// should be equal to address of pptr