<p>const位置决定语义:紧邻谁就修饰谁,int const p和const int p均表示指向常量的指针(p不可改),int const p表示指针常量(p不可改),const int* const p二者皆不可改。</p>

const在指针声明中位置决定语义
读法不是靠死记“左值右值”,而是看const紧挨着谁:它修饰紧邻的类型或标识符。C++里const是“向左绑定”(除非左边没东西,就往右绑)。比如int const* p和const int* p完全等价,都表示“p是指向const int的指针”,即不能通过p改所指内容;而int* const p表示“p是const指针”,即p本身不能指向别处。
三种常见组合及典型错误现象
实际写代码时容易混淆的其实是这三种情况,编译器报错信息往往直指本质:
-
const int* p→ 改*p报错:error: assignment of read-only location '* p';改p合法 -
int* const p = &x→ 改p报错:error: assignment of read-only variable 'p';改*p合法(前提是x非常量) -
const int* const p = &x→ 两者都改不了,两个错误都会触发
为什么int const*比const int*更利于理解
把const放在类型名后面(如int const*),能更自然地体现“int是const的,然后这个const int被指针指向”。尤其在复杂类型中优势明显,比如std::vector<int> const* p</int>,一眼看出p指向一个不可修改的vector;而const std::vector<int>* p</int>容易误读成“vector里的int是const”。STL容器迭代器常用这种风格:std::vector<int>::const_iterator</int>本质就是int const*的泛化。
函数参数里用const指针的真实意图
写void func(const int* p)不是为了“保护p不被重赋值”,而是告诉调用者:“我只读*p,不会改你传进来的数据”。此时p本身在函数内完全可以重新指向,但没人这么干——因为语义上它代表“输入数据源”。真正要禁止指针重定向,得用void func(int* const p),但这极少出现,既难读又无实际约束力(调用方传进来的临时指针变量本就不能被函数修改地址)。
立即学习“C++免费学习笔记(深入)”;
复杂点在于嵌套:比如const char* const* argv,从右往左读——“argv是指向const指针的const指针”,即argv不能变,它指向的那个指针也不能变,但那个指针所指的字符串内容是否可变,还得看最左边的const char*部分。这种地方光靠读法不够,得结合使用场景判断设计意图。


















