const修饰指针的关键是看const紧邻谁:左无物则看右,右为*修饰指针本身,右为类型则修饰所指对象;从右向左读最稳妥。

const修饰指针的三种写法怎么区分
关键看const紧挨着谁:它左边没东西就看右边,右边是*就修饰指针本身(指针不可变),右边是类型就修饰所指对象(内容不可变)。最稳妥的方式是「从右往左读」。
常见混淆点是const int* p和int const* p完全等价(const在*左边,修饰int),而int* const p中const在*右边,修饰指针变量p本身。
-
const int* p或int const* p:指针可改,指向的内容不可通过p修改 -
int* const p = &x:指针初始化后不能指向别处,但*p可赋值 -
const int* const p = &x:指针和所指内容都不可变
函数参数里传const指针为什么常写成const T*
这是为了在函数内部禁止修改调用方传来的数据,同时不约束指针本身——函数可以移动指针遍历数组,但不能改原值。比如strlen(const char*)就是典型应用。
如果写成char* const p,只是保证函数里不会让p指向别处,对调用方几乎无保护意义,还可能误导使用者以为数据安全了。
- 接口设计优先用
const T*(保护数据)而非T* const(只保护指针) - 若函数内部需修改指针值(如解析字符串时递增),就不能用
T* const,否则编译不过 - 传入字面量字符串时,必须用
const char*,否则"hello"隐式转char*在C++11后已弃用
const指针和constexpr指针容易搞混的地方
const指针只要求运行期不可变;constexpr指针要求编译期就能确定地址且所指对象也是字面量或constexpr变量。两者语义不同,不能互相替代。
例如constexpr int* p = &x要求x必须是constexpr int x = 42;,而const int* p = &x哪怕x是普通局部变量也合法。
-
const int* p→ 运行期禁止写*p -
int* const p→ 运行期禁止改p的值 -
constexpr int* p→ 编译期就必须知道p指向哪,且目标必须有静态存储期
用auto推导const指针时要注意什么
auto默认忽略顶层const,所以const int* p = &x; auto q = p;得到的是int*,不是const int*。要保留const得显式写const auto*或auto const*。
更安全的做法是直接用decltype:如果希望q和p类型完全一致,写decltype(p) q = p;。
-
auto p = const_ptr;→ 推导为去掉顶层const的类型 -
const auto* p = ptr;→ 明确要求指针所指为const -
auto const* p = ptr;→ 同上,const位置不影响语义
实际写代码时,最容易漏掉的是函数参数用const T*来表达「只读访问」意图,以及用auto时误以为它会保留原始声明里的const限定。这两处不注意,轻则逻辑漏洞,重则引发未定义行为。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











