const int p 是指向常量的指针,p 可改但 p 不可改;int const p 是常量指针,p 不可改但 p 可改;两者叠加为 const int* const p,指针和值均不可变,且必须初始化。

const int* p 和 int* const p 有什么区别
常量指针的语义容易混淆,关键看 const 修饰谁:它紧挨着谁,就限制谁。前者是“指向常量的指针”,后者才是“常量指针”——指针本身不可变。
-
const int* p:p可以改(指向别的地址),但不能通过p修改它指向的值(比如*p = 5报错) -
int* const p:p初始化后不能再赋新地址(比如p = &x报错),但*p = 5合法 - 两者可叠加:
const int* const p,指针和它指向的内容都不可变
初始化时必须赋值,否则编译失败
int* const p 是常量,声明即绑定地址,没初始化就用等于未定义行为,编译器直接拒绝。
- ✅ 正确:
int x = 10; int* const p = &x; - ❌ 错误:
int* const p; p = &x;—— 编译报错:error: uninitialized const variable 'p' - ⚠️ 注意:引用也有类似约束,但指针更易忽略这点
常量指针在函数参数中常见用途
传参时用 int* const p 主要防止函数内部意外重绑定指针,但不保护数据;若想同时保护数据,得用 const int* const p。
- 场景:API 要求你只操作某个固定内存块,不允许挪动指针本身
- 示例:
void process_data(int* const buf) { /* buf++ 或 buf = nullptr 都非法 */ } - 对比:
void process_data(const int* buf)允许buf++,但禁止*buf = ...
别和 constexpr 混用,它们解决不同问题
constexpr int* p 要求指针值和所指对象都在编译期确定,而 int* const p 只是运行期不可再赋值。多数情况只需要后者。
-
constexpr指针必须指向静态存储期对象(如全局变量、static局部变量) -
int x = 1; int* const p = &x;合法,但constexpr int* p = &x;编译失败 - 真正需要
constexpr的场景极少,比如模板元编程或数组大小推导
实际写代码时,先问自己:我要锁住的是“地址”还是“值”,还是两者都要。选错类型会导致编译错误或逻辑漏洞,而且这类错误往往在修改函数实现时才暴露。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











