我正在尝试使用指针来更好地掌握它,我在这里遇到了这种情况: 我声明了一个变量 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
)的位置。
编译器可能会使用复杂的算法来为对象分配内存。然而,在这个有限的问题上,我们可以考虑一个简单化的观点。本质上,编译器准备需要存储在堆栈上的对象的信息,然后为这些对象在
main
的堆栈帧中分配位置,结果是它分配位置的第一个对象将最终位于地址 0061FF14 16,下一个在 0061FF1816,下一个在 0061FF1C16。 (堆栈帧中还有其他内容,这就是为什么我们在本例中看到的第一个对象从 0061FF1416 开始,而不是 0061FF1016 开始。)
在程序的第一个版本中,程序打印
var
、ptr
和 pptr
的地址。所以这些对象必须有地址。无论出于何种原因,编译器都会按照 pptr
、ptr
和 var
的顺序处理它们,分别为它们提供地址 0061FF1416、0061FF1816 和 0061FF1C16。
在程序的第二个版本中,程序打印
var
和 ptr
的地址(后者通过将 &ptr
分配给 pptr
然后打印 pptr
)。它从不使用 pptr
的地址,因此 pptr
不需要有实际地址;编译器无需将 pptr
放入内存即可使程序运行。因此,对于这个程序,编译器为 var
和 ptr
分配内存,它们最终位于地址 0061FF1416 和 0061FF1816。因此 ptr
的地址与程序的第一个版本相差四个字节。