const int p不能改值但可改地址,int const p不能改地址但可改值;const int const p二者均不可改;int const p与const int* p等价;typedef易致const作用对象误解。

const int* p 和 int* const p 到底谁不能改
关键看 const 紧挨着谁:左边修饰指针指向的值,右边修饰指针本身。
const int* p 表示“指向常量整数的指针”——不能通过 p 修改它指向的值,但 p 本身可以指向别处;int* const p 表示“常量指针”,指针地址不可变,但能修改它指向的值。
-
const int* p = &x;→*p = 5;报错(不能改值),p = &y;合法(可换地址) -
int* const p = &x;→*p = 5;合法(可改值),p = &y;报错(地址已锁定) - 两者都能写成
int const* p,等价于const int* p(const在*左边)
const int* const p:双重锁定怎么用
这是最严格的写法,指针和它指向的值都不可变。常见于函数参数传递,避免意外修改数据或误重定向指针。
- 声明时必须初始化:
const int* const p = &x;,否则编译失败 - 传参时常用:
void func(const char* const str),既防止函数内改字符串内容,也防改指针本身(虽后者少见) - 注意:它不等于“只读内存”,只是编译期约束;若原变量非
const,仍可通过其他非 const 指针修改值
为什么 int const * p 和 const int * p 完全等价
C++ 声明遵循“从右向左读”规则:int const * p 读作“p 是一个指向 const int 的指针”,和 const int * p 语义一致。编译器不区分二者顺序。
立即学习“C++免费学习笔记(深入)”;
- 但
int * const p必须把const放在*右边,否则变成int * const p(合法) vsconst int * p(不同含义) - 建议统一用
const靠左风格(如const T*),与 STL 容器 const_iterator 习惯一致,降低认知负担 - Clang/GCC 对两种写法完全兼容,无需担心跨编译器问题
容易踩的坑:typedef 和 const 结合时的陷阱
用 typedef 定义指针类型后加 const,很容易误解作用对象。
-
typedef int* IntPtr;→const IntPtr p;等价于int* const p;(指针常量),不是const int* p - 原因:
const修饰的是IntPtr这个类型名整体,而IntPtr本身是“指针类型” - 要得到“指向 const int 的指针”,得写
const int* p;或typedef const int* ConstIntPtr; - C++11 起推荐用
using IntPtr = int*;,行为一致,但语义更清晰
实际编码中,最容易忽略的是 typedef 场景下的 const 作用对象,以及误以为 const int* p 能防止别人修改原变量——它只约束通过该指针的访问路径。










