是的,const int p 和 int const p 完全等价,均表示指向常量整数的指针:指针p本身可修改(能重新指向其他地址),但不能通过*p修改其所指向的值。

const int* p 和 int const* p 是一回事吗?
是的,const int* 和 int const* 完全等价,都表示「指向常量 int 的指针」——指针可以改(指向别的地址),但不能通过它修改所指的值。
常见错误是以为 const 修饰的是指针本身,其实它紧贴类型(int),所以修饰的是「被指向的内容」。
-
const int* p = &x;→ ✅ 允许p = &y;,但禁止*p = 5; -
int* const p = &x;→ ❌ 这才是「常量指针」:p 不能改,但*p = 5;合法 -
const int* const p = &x;→ ⚠️ 指针和内容都不可变
为什么传参时常用 const int*?
函数接收数组或缓冲区时,用 const int* 能同时做到两件事:避免意外修改原始数据 + 允许编译器做更多优化(比如假设该内存不会被写入)。
例如:
void print_array(const int* arr, size_t n) {
for (size_t i = 0; i
- 调用
print_array(nums, 5)时,即使nums是非常量数组,也安全 - 如果误写成
int* arr,调用者可能误以为函数会修改数据,且失去 const 正确性约束 - 某些嵌入式或性能敏感场景,编译器对
const指针所指内存可能启用只读缓存优化
和 constexpr、const 引用混用时要注意什么?
const int* 不等于「指向编译期常量」,它只是运行期只读访问权限。即使指向 constexpr 变量,也不能靠它推导出编译期常量表达式。
-
constexpr int x = 42;+const int* p = &x;→p是运行期指针,*p仍是常量表达式(因为x是 constexpr) -
const int y = 10;+const int* p = &y;→*p不是常量表达式(y是运行期初始化) - 想确保只读且编译期可知,优先用
constexpr或const&,而不是依赖指针的 const
容易忽略的隐式转换陷阱
C++ 允许从 int* 隐式转为 const int*(安全:加限制),但反过来绝对不行。
典型翻车点:
- 把
std::vector<int>::data()</int>(返回int*)直接赋给const int*→ 合法,没问题 - 函数参数是
const int*,你传了int*→ 合法,但别以为函数内部能改原值(它不能) - 若函数内部需要修改,却误用了
const int*参数 → 编译失败,得改签名,不是加const_cast(那是危险信号) - 模板推导中,
T*推不出const T*,需显式指定或加const限定
真正难缠的,是跨层传递时 const 语义被无意弱化——比如某中间函数把 const int* 转成了 int* 再传下去,整个只读契约就断了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











