为何(&p1)[i][j]无法正确获取二维数组元素?与行指针p2的差异
为什么(&p1)[i][j]无法像p2[i][j]一样正确访问二维数组?
先看你给出的代码定义:
列指针p1的定义
int a[3][4]={{1,3,5,7}, {9,11,13,15}, {17,19,21,23}}; int *p1= &a[0][0];
p1是指向int的指针,p1[i]等价于*(p1+i),会从p1指向的地址开始偏移i个int的大小,所以p1[4]能取到9,这部分没问题。
行指针p2的定义
int (*p2)[4] = a;
p2是指向包含4个int元素的数组的指针(也就是行指针)。二维数组名a会隐式转换成指向其第一行的指针,类型正好是int(*)[4],所以p2[i][j]等价于*(*(p2+i)+j),能正确获取a[i][j]的值。
核心问题:&p1和p2的类型完全不同
你误以为&p1和p2等价,但实际上:
- p1的类型是
int*,所以&p1的类型是int**(指向指针的指针); - p2的类型是
int(*)[4](指向长度为4的int数组的指针)。
这两种类型没有任何等价关系,不能混用。
为什么部分结果看起来“正确”?
(&p1)[0][j]等价于p1[j]:因为(&p1)[0]就是*(&p1),也就是p1本身,所以这部分写法本质还是用p1访问数组,自然能得到正确结果;- 但
(&p1)[1][0]这类写法属于未定义行为:(&p1)[1]等价于*(&p1 +1),也就是从p1所在的内存地址,往后偏移一个int*大小的位置取内容。这个位置的内存不属于你定义的变量,内容是随机的,把它当成指针解引用的结果完全不可控,偶尔看起来“正确”只是巧合,本质是非法访问内存。
总结
想要用行指针的方式访问二维数组,必须使用int(*)[N](N是每行元素个数)类型的指针,而&p1是指向指针的指针,和行指针类型不匹配,不能用来替代行指针。
内容的提问来源于stack exchange,提问作者XY W
相关产品推荐
相关产品推荐

