使用指针访问数组元素的疑问:为何*(ptr+i)对应数组下一个索引
为什么指针加法在不同类型数组中都能指向正确的下一个元素?
这是个非常好的问题,刚好触及了C/C++指针算术的核心设计逻辑——指针加法是「类型感知」的,它不会固定偏移1字节,而是根据指针指向的元素类型大小来计算实际的内存偏移量。
让我一步步帮你拆解清楚:
1. 数组名到指针的隐式转换
首先要明确:在几乎所有场景下,数组名会自动转换成指向数组第一个元素的指针:
arr1(原本是int[5]类型)会被转换成int*类型的指针,指向arr1[0];arr2(原本是char[5]类型)会被转换成char*类型的指针,指向arr2[0]。
2. 指针加法的核心规则
当你对一个T*类型的指针执行ptr + n操作时(T是任意数据类型,n是整数),实际的内存地址偏移量是:
偏移字节数 = n * sizeof(T)
这个规则是C/C++语言内置的,目的就是让指针操作完美适配数组的连续存储结构——因为数组的每个元素都会占用sizeof(T)字节的连续内存空间。
对应你的代码例子:
- 对于
arr1(int*类型):假设你的平台上sizeof(int) = 4(这是大多数现代平台的情况),那么arr1 + 1会把地址偏移1 * 4 = 4字节,刚好跳过一个完整的int元素,直接指向arr1[1]的内存位置,所以*(arr1 + 1)自然就等于arr1[1]的值2。 - 对于
arr2(char*类型):C标准规定sizeof(char)永远是1,所以arr2 + 1只偏移1字节,指向arr2[1]的位置,这和你已经理解的逻辑一致。
3. 数组索引的本质
其实你平时写的arr[i],本质上就是*(arr + i)的语法糖——这也是为什么不管数组元素是什么类型,arr[i]都能正确访问第i个元素的原因,底层都是用这种类型感知的指针加法实现的。
直观验证的小技巧
你可以打印指针的实际地址来亲眼看到偏移量差异:
#include <iostream> using namespace std; int main() { int arr1[5] = {1,2,3,4,5}; char arr2[5] = {'a','b','c','d','e'}; cout << "arr1 起始地址: " << (void*)arr1 << endl; cout << "arr1+1 的地址: " << (void*)(arr1 + 1) << endl; // 地址差4字节(取决于int的大小) cout << "\narr2 起始地址: " << (void*)arr2 << endl; cout << "arr2+1 的地址: " << (void*)(arr2 + 1) << endl; // 地址差1字节 return 0; }
运行这段代码,你会清晰看到不同类型指针加1后,地址偏移的字节数完全对应元素的类型大小。
内容的提问来源于stack exchange,提问作者Ashu
相关产品推荐
相关产品推荐

