const int ()[n] 是指向常量数组的指针,紧贴括号表示指针类型,数组维度n是类型一部分;而 const int* p 仅表示指向常量元素的指针,不涉及数组整体。

const int* p 指向常量元素的指针,不是指向常量数组的指针
很多人看到“指向常量数组的指针”,第一反应是写 const int* p,但这其实是指向“常量 int”的指针,即不能通过 p 修改它所指的单个元素,但 p 本身可以指向别的地址,也能指向普通数组、堆内存、甚至单个变量——它根本不管“数组”这件事。
真正要表达“指向一个整体不可变的数组”,关键在数组类型本身带长度信息,且该数组对象是 const 的。C++ 中数组类型包含大小,所以必须把维度作为类型一部分参与声明。
- 若数组是栈上定义的:比如
const int arr[5] = {1,2,3,4,5};,那么指向它的指针类型是const int (*)[5] -
const int (*)[5]是“指向含 5 个const int的数组”的指针,*紧贴括号,表示“指针”,不是“指针所指的元素是 const” - 错误写法:
const int* p[5]是含 5 个const int*的数组;int const* p和const int* p等价,仍是元素级 const
怎么声明并初始化指向常量数组的指针
直接用类型推导最安全,避免手写复杂语法出错:
const int arr[3] = {10, 20, 30};
auto* p = &arr; // p 类型自动推导为 const int (*)[3]
如果必须显式写类型,注意括号不能省:
- 正确:
const int (*p)[3] = &arr;——(*p)表示解引用后是个数组,[3]是数组维度 - 错误:
const int* p[3](这是数组)、const int* p = arr;(退化为指针,丢失长度信息) - 初始化时必须用取地址符
&arr,因为arr本身会隐式转成const int*,而我们需要的是“指向整个数组对象”的地址
为什么不能用 std::array 或 vector 替代?
如果你只是想安全访问固定大小的常量集合,std::array<const int></const> 更现代、更易用。但它和原生数组指针不是同一概念:
-
std::array是类模板,&a得到的是std::array<const int>* </const>,不是const int (*)[3] - C 风格接口(如某些系统 API、嵌入式驱动)往往要求传
const int (*)[N]这种类型,此时必须用原生语法 - sizeof(*p) 在
const int (*p)[5]下等于5 * sizeof(int),能反映完整数组大小;而const int* p解引用只占一个int大小
常见编译错误和排查线索
写错时编译器通常报类型不匹配,典型错误信息包括:
-
cannot convert 'const int*' to 'const int (*)[4]' in initialization—— 忘了加&,写了p = arr而不是p = &arr -
invalid conversion from 'int*' to 'const int (*)[3]'—— 源数组没加const,比如int arr[3];,但目标指针要求整个数组是 const 的 - 函数参数声明为
void f(const int (*)[N]),却传了arr(退化指针)而不是&arr,也会触发类似错误
最容易被忽略的是:数组字面量(如 {1,2,3})无法直接取地址,必须先绑定到具名 const 数组变量,否则连 & 都无处可加。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











