结论:数组场景下常量指针与指针常量的区分逻辑不变,关键看const相对于的位置;const在左为指向常量的指针(可换数组、不可改内容),在*右为指针常量(不可换数组、可改内容),二者结合则完全不可变。

直接说结论:数组场景下,常量指针和指针常量的区分逻辑完全不变,只是目标从单个变量变成了数组首地址或数组元素;关键看 const 相对于 * 的位置,不是看它是不是在数组里。
const 在 * 左边:指向数组元素的常量指针
比如 const int* arr_ptr 或 int const* arr_ptr,声明的是“指向 int 常量的指针”,arr_ptr 本身可变,但不能通过它改数组内容。
- 常见错误现象:
arr_ptr[0] = 5;或*arr_ptr = 5;编译失败,报错类似assignment of read-only location - 合法操作:可以赋值为不同数组的首地址,比如
arr_ptr = another_arr;(前提是类型匹配) - 典型用途:函数参数中接收只读数组,如
void print(const int* data, int n),确保不意外修改原数组
const 在 * 右边:指向数组的指针常量
比如 int* const ptr_to_arr,声明的是“指向 int 的常量指针”,ptr_to_arr 初始化后不能再指向别的数组,但能改它所指数组的元素。
- 常见错误现象:
ptr_to_arr = another_arr;编译失败,报错类似assignment of read-only variable - 合法操作:
ptr_to_arr[0] = 42;或*(ptr_to_arr + 1) = 99;都允许 - 注意:这里
ptr_to_arr指向的是数组首元素地址,不是整个数组对象;若想固定指向“整个数组”,需用数组指针语法,如int (*const arr_ptr)[5] = &my_arr;
数组名本身不是指针,但常被隐式转成常量指针
像 int arr[5] = {1,2,3,4,5}; 中的 arr 是数组名,类型是 int[5],不是指针。但在大多数表达式中(如传参、赋值给指针),它会自动退化为 int* 类型的右值 —— 这个右值等效于一个临时的、指向首元素的常量指针(不可取地址、不可赋值)。
- 所以
int* p = arr;合法,但arr = p;编译错误(arr不是左值) - 而
const int* p = arr;更安全,明确禁止通过p修改数组 - 容易踩的坑:误以为
arr是指针常量 —— 它根本不是变量,连“常量”都谈不上;它是编译期确定的地址符号
真正容易忽略的是:当你要让一个指针既固定指向某个数组、又禁止修改该数组内容时,得写成 const int* const ptr —— 两个 const 缺一不可。少一个,语义就变了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











