通过指针引用多维数组
如何理解二维数组元素的地址?
要知道,这本书用了整整两页的内容来讲解这方面的知识,从这里足以看出来理解通过指针来引用二维数组是一件比较麻烦的事情,但是我认为理解并不难。
- 什么是二维数组?
举个例子:int a[3][4]={ {1,3,5,7},{9,11,13,15},{17,19,21,23}};
a是二维数组名,可以看成一个大数组“包着”三个小数组:
大数组(管理小数组的数组)a包含三个元素(小数组):a[0],a[1],a[2]。小数组a[0]包括四个元素:1,3,5,7。小数组a[1]包括四个元素:9,11,13,15。小数组a[2]包括四个元素:17,19,21,23。
二维数组:“小数组的大数组”
一.数组名a和&a[i]
回到我们指针的内容,之前我们理解过,数组名代表该数组首元素的地址(
&a[0]
),那么这里的二维数组名也可以这样子理解为是&a[0]
,但是我们上面提到,a[0]也是一个数组,那么&a[0]
代表的是什么意思呢?事实上,它是一种地址的计算方法,得到的答案是小数组a[0]首元素的地址。- 从我上面所述的二维数组是“小数组的大数组”观点来看,数组名a与二维数组首元素的地址(&a[0])等价,但是由于这里首元素a[0]是一个小数组,我们可以看作a指向大数组的第一个元素:小数组a[0] 的第一个元素a[0][0]。也就是说,数组名a的值是
&a[0][0]
。类比可得:
&a[i]
就是小数组a[i]首元素的地址。
二.a+i是什么?
- 根据前面的知识,我们大概可以猜出a+1是地址,那么它所指向的内存是什么呢?
- 前文提到:a指向大数组的第一个元素:小数组a[0] 的第一个元素a[0][0]。那么a+1则指向大数组的第二个元素:小数组a[1] 的第一个元素a[1][0],或者说a+1是小数组a[1]的首元素的地址。从内存来看,假定内存名为a的内存(存放
&a[0][0]
)的地址是2000,a+1的值则是2000+4×4=2016。- 以此类推,a+i指向大数组的第i+1个元素:小数组a[i] 的第一个元素a[i][0]。
- 由此可以得出以下重要的等价关系:
1.a+i与
&a[i]
(实际上是&a[i][0])等价。2.
*(a+i)
与a[i]等价(二者都是地址)。
三.a[i]+j是什么?
- 在一维数组
int a[3]={1,2,3}
中,a+1(指针:存放a[1]的地址)指向a[1],即1.a+1与&a[1]
等价。2.*(a+1)
与a[1]等价。- 那么在一维数组中,1.a+i与&a[i]等价。 2.
*(a+i)
与a[1]等价。- 回到我们的二维数组,a[i]是小数组名,同理有如下等价关系,请务必记住:
1.a[i]+j与
&a[i][j]
等价2.
*(a[i]+j)
与a[i][j]等价3.由上文二.2和三.2的等价关系可得:
*(*(a+i)+j)
与a[i][j]等价。
理解上面很抽象的内容是不是很痛苦呢,我在接触指针的时候也绕了很多弯