int *p = a
,按字面意思解释,获取存储在中的值a
并尝试将其解释为要存储在中的内存地址p
。虽然在计算上是合法的,但如果没有明确的类型转换,C++ 将不允许这样做,因为这通常不是您想要做的。
int *p = a
语句不同的原因*p = a
很简单:第一个语句,下面的简写
int *p;
p = a;
正在初始化指针,因此它期望 RHS 上的内存地址,而第二条语句正在为 指向的位置分配一个值p
,因此期望(在这种情况下)RHS 上的整数。
如果你想初始化p
指向a
,你可以使用int * p = &a
orp = &a
代替,where &
is the address-of 操作符。永远不要尝试取消引用未初始化的指针!您最终会在一个基本上任意的位置接触内存,这可能会导致分段错误(导致崩溃)或开始覆盖程序中的其他数据(导致模糊和不可重现的错误)。
当您运行示例代码时,p
并且&a
具有不同的值正是因为p
从未分配到指向a
. 关于为什么你可能会得到任何非零值的一些简短背景p
:局部变量是从称为堆栈的特殊内存区域分配的,它还存储有关函数调用和返回地址的信息。每个进程都有自己的堆栈。然而,至关重要的是,堆栈中未使用的区域在使用之前并没有真正清零或以其他方式清理(可能在调试版本中除外,它往往会分配非常明显的值,例如0xCCCCCCCC
或0xBAADF00D
到未初始化的指针)。如果您的编译器没有自动为您设置默认值(并且发布版本通常不会有这样的自动初始化,为了提高效率),那么您所看到的p
是发生p
在您的程序设置之前分配给的内存中的内容向上它的堆栈帧。