指针遍历数组时arr自动退化为int*,可直接赋值给指针变量并递增访问;常见错误是循环条件未限制p
用指针访问数组首地址后递增遍历
数组名在大多数上下文中会自动退化为指向首元素的指针,所以
int arr[5]的arr本身就可以当int*用。遍历时只需用指针变量接收它,再通过++或+=移动位置。常见错误是越界:比如写
for (int* p = arr; p ,<code>arr + 5已经是末尾元素的下一个地址(合法但不可读),解引用它会触发未定义行为。
- 正确边界判断用
p != arr + n或p (<code>n是元素个数)- 避免混用
sizeof(arr)计算长度——若arr是函数参数,sizeof返回指针大小而非数组总字节数- 推荐用
std::size(arr)(C++17 起)或模板推导获取长度,但仅适用于原生数组且非形参用指针偏移语法
ptr[i]替代*(ptr + i)
ptr[i]和*(ptr + i)完全等价,编译器生成的汇编通常一致。选ptr[i]更符合阅读直觉,尤其在多层嵌套或条件索引时。注意:这不意味着你在“用数组方式访问”,底层仍是纯指针运算。例如
int* p = arr + 2;后,p[0]是第三个元素,p[1]是第四个——下标始终相对于当前指针位置。
- 不要误以为
p[i]会自动绑定到原始数组起始位置- 若需固定基址访问,显式写成
arr[i]或保存原始指针副本- 性能无差异,但
ptr[i]在复杂表达式中可读性更高(如(p + offset)[i])传入函数后如何安全遍历(避免退化陷阱)
函数参数写
void func(int arr[])或void func(int* arr),实际都是接收指针,sizeof(arr)永远是sizeof(int*)。此时必须额外传长度。
C++ Code Review Master下载组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
典型错误是试图在函数内用
sizeof(arr)/sizeof(arr[0])算长度,结果得到 8/4=2(64 位系统),导致遍历崩溃。
- 强制要求调用方传入长度:
void func(int* arr, size_t n)- 用模板推导(适用于编译期已知大小的数组):
template<size_t n> void func(int (&arr)[N]) { /* sizeof(arr) 正确 */ }</size_t>- C++20 可考虑
std::span<int></int>,自带长度信息且不拷贝数据为什么不用
std::vector?什么场景还必须用原生指针除非对接 C API、嵌入式裸机、高性能计算内核或已有大量 C 风格接口,否则优先用
std::vector。它的迭代器本质就是带边界检查(Debug 模式)和容量管理的指针封装。原生指针遍历的不可替代场景:需要精确控制内存布局(如 GPU 显存映射)、规避任何 STL 运行时开销、或实现底层容器(如
vector自身的迭代器)。
std::vector::data()返回的就是T*,可直接用于传统指针遍历- 调试时打印
&arr[0]和arr.data()地址相同,说明底层连续- 真正难的是生命周期管理——指针不管理内存,忘了
delete[]或重复释放,问题比容器更隐蔽C++ 指针遍历本身很简单,难点全在边界控制、生命周期归属和上下文语义理解上。尤其是传参后数组退化这个点,几乎每个 C++ 初学者都踩过坑。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!












