一、const 核心本质
const 修饰的内存数据,只读、不可写。
变量与常量本质区别:
普通变量:内存可读、可修改
const 常量:内存仅可读、禁止修改
int a = 5; a = 1024; // 合法 const int b = 5; b = 360; // 报错:常量不可修改二、指针的两层实体(所有题的根源)
任意指针int *p =&a 永远包含两个对象:
p:指针本身(存地址),控制「指针指向哪里」
*p:指针解引用(代表目标内存的值),控制「目标内存能不能改」
终极判断规则: const 靠近谁,谁就只读;远离谁,谁就可改。
三、三种 const 指针(精解+最简记忆)
1. 常量指针:const int *p/int const *p(等价)
语义:*p 只读,p 可改
不能通过指针修改目标值:
*p = 100报错可以修改指针指向:
p = &b合法
关键真相:仅收窄指针权限。如果原变量没有 const,原变量依然可以直接修改,只是不能通过这个指针改。
int a = 5; const int *p = &a; a = 666; // 合法:原变量可改 *p = 999; // 报错:指针被const限制 p = &(int){20}; // 合法:指针可换指向2. 指针常量:int * const p
语义:p 只读,*p 可改
指针指向固定不可变:
p = &b报错可以修改目标内容:
*p = 100合法
强制规则:定义时必须初始化地址。
int a = 5; int * const p = &a; *p = 888; // 合法 p = &(int){20}; // 报错:指针本身是 常量3. 双重只读指针:const int * const p
语义:p、*p 全部只读
不能改指向、不能改内容
定义必须初始化,全程只读
四、一秒背诵口诀(永久不混)
const 在 * 左边 → 内容只读,指针可动(常量指针)
const 在 * 右边 → 指针只读,内容可动(指针常量)
左右都有 const → 全都不动
五、核心权限对照表(极简版)
写法 | 改指向(p) | 改内容(*p) | 名称 |
|---|---|---|---|
const int *p | ✅ 可改 | ❌ 不可改 | 常量指针 |
int * const p | ❌ 不可改 | ✅ 可改 | 指针常量 |
const int * const p | ❌ 不可改 | ❌ 不可改 | 双重只读指针 |
六、最高频考点:const 权限匹配规则
1)普通变量 → const 指针(合法)
内存可写,指针主动降低权限,安全合规。
int a = 10; const int *p = &a; // 合法:收窄权限2)const 常量 → 普通指针(报错)
代码
const int a = 10; int *p = &a; // 编译报错:丢弃const限定正确原理(核心):
const int a的内存是纯只读内存。
int*是可读写的高权限指针。把只读内存交给可写指针=权限放大、丢弃只读限制。
编译器直接拦截,杜绝通过指针篡改常量的未定义行为。
七、最终精华易错总结
const int *p只是指针不能写,原变量无 const 依然能直接改;int * const p指向固定,必须初始化;权限只能收窄,不能放大(普通指针不能接 const 地址);
const int *p和int const *p完全等价。