C语言中二维数组名指向什么?为何*(arr+8)无法访问arr[1][0]
核心原理:指针运算的步长由指向类型决定
C语言中所有指针加法运算都遵守同一规则:偏移的实际字节数 = 偏移量 × sizeof(指针指向的元素类型),二维数组的指针操作差异本质是不同指针的指向类型不同,导致步长不同。
问题具体拆解
你给出的代码中涉及两类完全不同的指针:
int *ptr = &arr[0][0];中ptr的类型是int *,指向的元素是int类型,步长为sizeof(int)。
所以ptr + 8的实际偏移是8 × sizeof(int),刚好跳过第一行的8个int元素,指向第二行首元素arr[1][0],赋值逻辑成立。- 数组名
arr对应的二维数组int arr[6][8]本质是元素为int[8]类型的一维数组,总共有6个元素。数组名arr参与运算时会退化为指向首元素的指针,指向的元素是int[8]类型(长度为8的int数组),步长为sizeof(int[8]) = 8 × sizeof(int)。- 所以
arr + 1的实际偏移是1 × 8 × sizeof(int),刚好跳过一整行数据,指向第二行的首地址,解引用*(arr + 1)得到arr[1]数组,该数组会继续退化为int *类型的指针指向arr[1][0],再次解引用*(*(arr + 1))即可对arr[1][0]赋值,这就是正确写法的底层逻辑。 - 而
arr + 8的实际偏移是8 × 8 × sizeof(int),相当于向后跳了8整行,你的数组总共只有6行(下标0~5),本身已经是越界访问非法内存,哪怕不越界,取到的也是下标为8的行的第0个元素,和你期望的arr[1][0]完全无关。
- 所以
常见二维数组相关指针类型对比
arr:退化为int (*)[8]类型,指向长度为8的int数组,步长为8 × sizeof(int)*arr(等价于arr[0]):退化为int *类型,指向int元素,步长为sizeof(int)&arr[0][0]:就是int *类型,和*arr步长完全一致
如果要模仿ptr + 8的逻辑用数组名实现同等效果,正确写法为*(*arr + 8) = 12,和你给出的*(ptr + 8) = 12完全等价。
内容的提问来源于stack exchange,提问作者std124_lf
相关产品推荐
相关产品推荐

