const修饰指针的关键是const与的相对位置:const在左(如const int p)表示指向常量的指针,可改地址、不可改值;const在右(如int* const p)表示指针常量,不可改地址、可改值;两者皆有则均不可改。

const 修饰指针时,关键看 const 和 * 的相对位置:const 在 * 左边是常量指针,const 在 * 右边是指针常量。 这不是记忆技巧,而是编译器解析规则——const 总是修饰它**紧邻的左侧标识符**;若在最左,则修饰右侧类型。
怎么读 const int* p 和 int* const p
别背“指向常量的指针”这种绕口定义。直接按书写顺序读:
-
const int* p→ “const int的*”,即“指向const int的指针”:能换地址(p = &b),不能改值(*p = 5报错) -
int* const p→ “int*的const”,即“int*类型的常量”:不能换地址(p = &b报错),能改值(*p = 5合法) -
const int* const p→ 两个限制都生效:既不能换地址,也不能改值
为什么 const int* p 能指向非常量变量?
因为它的约束只作用于**通过该指针的访问路径**,不干涉变量本身的可变性。常见误判是以为它只能指向 const 变量,其实:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
int a = 10; const int* p = &a;✅ 合法 -
*p = 20;❌ 编译错误:assignment of read-only location '* p' -
a = 20;✅ 合法 —— 值变了,*p读出来也是 20 -
const int b = 30; p = &b;✅ 也合法,只是更“安全”
这也是 strcmp(const char*, const char*) 能接收 char* 实参的原因:函数承诺不改你的字符串,但你传什么类型它不管。
声明时漏初始化会出什么问题?
仅对指针常量(int* const p)是硬性要求;常量指针(const int* p)可以延迟赋值:
-
int* const p;→ 编译错误:uninitialized const variable 'p',必须写成int* const p = &a; -
const int* p;→ 合法,后续再赋值:p = &a; - 混淆点:有人误以为所有
const变量都必须就地初始化,但这里const修饰的是指针所指内容,不是指针本身(除非const在*右侧)
最容易被忽略的是:const 位置一旦写错,语义彻底反转,且编译器不会报“你可能写错了”,只会安静地按语法执行。写完指针声明后,花三秒盯一眼 const 和 * 谁左谁右,比后期 debug 野指针或只读写失败快得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










