为了更好的理解二维数组指针,首先我们先来理解一维数组(多维数组的理解以此类推)。
定义一个一维的数组 int kk[3] = {1, 2, 3};
这时候对于kk这个变量怎么理解呢?因为kk表示一个数组,且数据类型为int,所以这是一个int 类型的数组指针。数据成员的存储结构如下:
数据成员在内存当中是连续存储的,具体占位多少个字节,跟数据成员的类型相关。
kk既是数组的地址,同时也等于该数组第一个成员(这里是整数1)的地址。即 kk = &kk[0]
通过数组下标序号访问该数组不同位置的成员。比如要获取数组kk第二个成员,kk[1],该成员的地址可以表示为&kk[1], 也可以写作 kk + 1(kk 是第一个成员的地址, +1表示向后跳一个数组成员寻址,具体跳多少个字节,跟成员数据类型相关,在这里+1是跳过4个字节找到kk[1])
接下来我们看二维数组
定义一个 2 *2的二维数组 int gg[2][2] = { {1, 2}, [3, 4]};
怎么理解这个二维数据呢,首先我们看下图:
在我们的视觉理解,这个gg应该是长得跟图中a一样,2*2的数组,然而从计算机存储角度理解,二维数组实际上是图中b。所以二维数组实际上也是一个数组,不过它存储的对象是数组,而不是一维数组里面具体的数值。我们用什么表示一个数组?数组指针,所以二维数组是一个存储数组指针的数组。数组名gg也是该数组的地址,且根据二维数组的存储结构,有gg = *gg = &gg[0][0],虽然三者的数值相同,但是三者的含义是不同的
gg 表示二维数组的地址
*gg 前面说了二维数组是数组的集合,我们用指针表示数组,所以也可以二维数组是数组指针的集合,对二维数组指针取消引用(*),得到的是其成员(数组指针) 。gg + 1 是该二维数组第二个成员,gg + 1跟gg[1]等价,不只是数值上相等
&gg[0][0] 这个很好理解,是先获取二维数组的第一个数组成员的第一个成员,然后再取址
所以,用一维数组的相关概念去类推二维数组的一些变量,就很好理解和区分了。
最后通过例题加深理解:
遍历二维数组gg的所有成员内的数值
方法1:for(int i = 0; i < 4; ++i){
printf("%d\n", *(*gg + i));
}
方法2:
for(int i = 0; i < 2; ++i){
for(int j = 0; j < 2; ++j){
printf("%d\n", (*(gg + i))[j]);
}}
方法3:
for(int i = 0; i < 2; ++i){
for(int j = 0; j < 2; ++j){
printf("%d\n", gg[i][j]);
}}