const对象是值不可变的变量,如const int x = 42;pointer to const(如const int* p)是指针可变但不可通过它修改所指内容;两者在初始化、可变性和生命周期上均不同。

const对象和pointer to const不是一回事
const对象是值不可变的变量,比如const int x = 42;;而pointer to const(指向const对象的指针)是指针本身可变、但不允许通过它修改所指内容,比如const int* p = &x;。两者生命周期、可变性、初始化要求都不同:const对象必须初始化,且整个生存期只读;pointer to const可以不指向const对象(比如指向普通int y),只是“承诺不改”——编译器只拦*p = 100这种写法,不拦y = 100。
怎么一眼看出const int* p修饰的是谁
用“const紧邻谁,就管谁”的经验规则:
-
const int* p→const紧邻int,修饰所指类型 → “指向const int的指针” -
int* const p→const紧邻p,修饰指针变量本身 → “p是const指针” -
const int* const p→ 两个const各管一边:所指值不可改,指针本身也不可改
别记中文名“常量指针/指针常量”,容易混淆;也别依赖“从右往左读”,遇到const int** p或int* const* p时反而绕晕。盯住const左边最近的标识符(类型或变量名)最稳。
为什么const int* p能指向非const变量却不能改它
这是C++的只读契约机制,不是内存保护:
- 允许
int y = 5; const int* p = &y;—— 合法,p只是承诺不通过自己改y - 禁止
*p = 6;—— 编译错误:assignment of read-only location '*p' - 但
y = 6;完全合法,*p随后读出来就是6
这种设计让函数接口更清晰:比如void f(const int* p)明确告诉调用者“我不会改你传来的值”,哪怕你传的是普通变量。
容易踩的坑:把const int* p当成int* const p来用
典型错误场景:
- 想固定指针指向却写成
const int* p = &x;→ 实际上p可以随时重赋值:p = &y;不报错 - 真要锁定指针本身,必须写
int* const p = &x;,且必须初始化(否则编译失败) - 混合使用时漏掉一个
const:const int* p = &x; *p = 10;报错,但p = &y;不报错;如果误以为p也不能动,逻辑就崩了
最危险的是在函数参数里传const T*却默认指针地址也不会变——它会变,只是值不会被你改。需要地址稳定,得显式写T* const或用引用。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











