指针变量是存储地址的变量,声明时属于变量名而非类型;必须初始化防野指针;&取地址、解引用不可混淆;数组名可退化为指针但不可修改。

指针变量不是“存数据的容器”,而是“存地址的变量”——定义时漏掉 * 或写错位置,编译器会直接报错或语义完全跑偏。
怎么写对指针变量的声明
核心就一条:* 属于变量名,不是类型的一部分。写成 int* p; 是常见但容易误导的风格;更准确的是 int *p;,强调 p 是一个“指向 int 的指针”。
-
int *p;✅ 正确:声明p为指针变量 -
int* p, q;❌ 危险:实际等价于int *p; int q;,q是普通int,不是指针 -
int * p;✅ 合法(空格不影响),但建议紧贴变量名保持可读性 - 多个指针要分开写:
int *p, *q, *r;
为什么初始化比赋值更重要
未初始化的指针(野指针)指向随机内存地址,解引用(*p)会导致未定义行为——程序可能崩溃、静默出错、甚至看似正常运行。
- 定义即初始化最安全:
int x = 42; int *p = &x; - 用
nullptr明确表示“暂不指向任何对象”:int *p = nullptr; - 绝不要写
int *p; *p = 10;—— 这里p根本没指向合法内存 - 局部指针变量不会自动初始化为
nullptr,必须显式写
取地址符 & 和解引用符 * 别混用
& 拿变量的地址,* 访问指针所指的值。它们是配对操作,但作用对象完全不同。
立即学习“C++免费学习笔记(深入)”;
int x = 100; int *p = &x; // &x → 得到 x 的地址,赋给 p int y = *p; // *p → 取 p 所指位置的值,即 x 的值 100
-
&p是“指针变量p自己的地址”,类型是int** -
*p是“p指向的那个int的值”,类型是int - 常见错误:
int *p = x;(把值当地址赋)或int *p = &x + 1;(越界地址,未定义)
指针和数组名在什么情况下能互换
数组名在大多数上下文中会自动退化为指向首元素的指针,但本质仍是常量地址,不能被赋值或自增。
-
int arr[5] = {1,2,3,4,5}; int *p = arr;✅ 等价于int *p = &arr[0]; -
arr = p;❌ 错误:数组名不可修改 -
arr[2]和*(arr + 2)等价,但arr本身不是变量,没有地址可取(&arr是另一个意思:整个数组的地址,类型为int(*)[5]) - 函数参数中
void f(int arr[])实际就是void f(int *arr),传的是首地址
真正容易出问题的,是把指针当成“更灵活的数组”来用,却忽略了它不携带长度信息、不检查边界、也不管理内存生命周期——这些都得靠程序员自己盯紧。










