<p>是的,const int 和 int const 完全等价,均表示指向常量int的指针,即不可通过p修改所指值,但p本身可重新赋值;而int const p表示常量指针,p不可变但所指值可修改;const int const p则二者皆不可变。</p>

const int* p 和 int const* p 是一回事吗
是的,const int* 和 int const* 完全等价,都表示「指向常量 int 的指针」——即指针所指向的值不能通过该指针修改,但指针本身可以重新赋值指向别的地址。
常见误判是以为 const 靠近哪个词就修饰哪个,其实它修饰的是左侧(若左侧无类型则修饰右侧),但这里两种写法语义一致,编译器不区分。
- ✅ 正确:
*p = 10;→ 编译错误(不能改值) - ✅ 正确:
p = &x;→ 允许(可以改指针指向) - ⚠️ 注意:如果
p指向的是非常量对象,只是限制“通过p改”,其他非常量指针仍可修改该对象
int* const p 怎么用
int* const p 是「常量指针」——指针本身不可变,必须初始化,且之后不能再指向别处;但它指向的值可以修改。
这种写法常用于函数内需要固定访问某块内存、又不想被意外重定向的场景,比如封装硬件寄存器地址或只读配置缓冲区的写入入口。
立即学习“C++免费学习笔记(深入)”;
- ✅ 正确:
*p = 42;→ 允许(值可变) - ❌ 错误:
p = &y;→ 编译失败(指针地址不可变) - ⚠️ 必须初始化:
int* const p = &x;,否则报错error: uninitialized const variable
const int* const p 是最严格的常量指针
const int* const p 同时限定「指针不可变」和「所指内容不可变」,也就是常说的「顶层 + 底层 const」。它既不能换地址,也不能改值。
适合声明全局只读资源的访问句柄,比如字符串字面量、ROM 映射区域首地址等。
- ❌
*p = 5;→ 编译错误 - ❌
p = &z;→ 编译错误 - ✅ 常见写法:
const char* const msg = "hello";,防止误操作破坏字符串或指针跳转 - ⚠️ 注意:如果底层对象本身不是 const(如
int x = 1;),那仍可通过其他非常量指针修改x,const只约束当前绑定
为什么用 typedef 或 using 定义常量指针容易出错
用 typedef 或 using 封装指针类型时,const 的位置极易误解。例如:
typedef int* IntPtr; const IntPtr p = &x; // 等价于 int* const p → 指针常量,不是指向常量!
这里 const 修饰的是 IntPtr 类型整体,而 IntPtr 是「指针类型」,所以结果是「常量指针」,不是「指向常量的指针」。
- ✅ 想要「指向常量的指针」,得写:
typedef const int* CIntPtr;或using CIntPtr = const int*; - ⚠️
const在类型定义外加,永远作用于整个别名,不穿透到指针目标类型 - ? 建议:对复杂指针类型,优先用
using+ 显式书写(如using PtrToConstInt = const int*;),避免歧义
实际编码中,最容易忽略的是 const 作用域的层级关系——它不改变对象本身的可变性,只约束当前绑定路径。写错一个 const 位置,可能让本该只读的数据被意外修改,也可能让本该灵活切换的指针变成死地址。


















