获取变量地址的唯一可靠方式是用取地址运算符&,如int p = &x;,表示p存储x的内存地址而非x的值;常见错误是漏写&,写成int p = x;会导致编译错误。

用 & 获取变量地址,赋给指针变量
指针和变量建立关联的唯一可靠方式,是把变量的内存地址存进指针变量里。这靠取地址运算符 & 完成:int* p = &x; —— 这行代码不是“让 p 等于 x”,而是“让 p 存下 x 在内存里的门牌号”。x 本身还在原地,p 只是记住了它的位置。
常见错误包括:
- 写成
int* p = x;(漏掉&),编译器会报错:无法把int赋给; - 对字面量取地址,如
&42或&"hello",多数情况非法(字符串字面量地址可取,但不可修改); - 对临时对象取地址,比如
int* p = &func();,结果未定义,因为临时对象可能在语句结束就销毁。
* 解引用才能读写变量值,不是指针本身
指针变量 p 存的是地址,它自己不是数据。要访问或修改 x 的值,必须用解引用操作符 *:*p = 100; 才真正把 x 改成 100;cout 输出的才是 <code>x 的当前值。
容易混淆的点:
立即学习“C++免费学习笔记(深入)”;
-
p和*p类型不同:p是int*,*p是int; cout 打印的是地址(如 <code>0x7ffeed42a9ac),cout 才打印内容;- 如果
p没初始化(比如只写了int* p;),直接*p = 5;会导致未定义行为——程序可能崩溃,也可能看似正常,但绝对不可靠。
指针可以重新指向别的变量,但不会自动同步生命周期
指针变量的值(即它存的地址)可以随时改:p = &y; 就让 p 指向另一个变量 y。这很灵活,但也带来风险:
- 原变量
x不会因p离开就失效,但它可能变成“没人再通过指针访问”的状态; - 如果
y是局部变量,函数返回后y被销毁,而p还指着那个地址,就成了悬空指针——*p的行为完全不可预测; - 多个指针指向同一变量时,其中一个执行
delete p;(且没置nullptr),其余指针立刻变悬空,后续解引用就是踩雷。
数组名、函数名天然可当地址用,但类型需留意
数组名(如 arr)在多数上下文中自动退化为指向首元素的指针,所以 int* p = arr; 合法,等价于 int* p = &arr[0];。函数名同理:void foo(); void (*fp)() = foo; 中,foo 本身代表函数入口地址。
但要注意隐式转换的边界:
-
sizeof(arr)返回整个数组字节数,sizeof(p)返回指针本身大小(64 位系统通常是 8); -
arr + 1指向第二个元素,p + 1同样,但这是基于指针算术——移动距离是sizeof(int)字节,不是简单加 1; - 函数指针不能直接用
&foo初始化(虽然很多编译器允许),标准写法是void (*fp)() = foo;,不加&更安全。
真正难的不是让指针“关联”上变量,而是确保这种关联在整段生命周期里始终有效、可预测。地址可以随时复制,但内存的生灭时机、作用域边界、多线程访问——这些才是让关联崩塌的常见原因。


















