首先,我们来先定义一个二维数组
int a[3][4]= {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
a是数组名,a是一个3行4列的数组。
a数组包含3行元素,即a[0],a[1],a[2]。而每一个行元素又是一个一维数组,它包含4个元素(即4个列元素),
例如,a[0] 所代表的一维数组又包含4个元素。a[0][0],a[0][1],a[0][2],a[0][3],可以认为二维数组是数组的数组,
即二维数组a是有3个数组所组成的。
我们可以知道,a是二维数组名,它也可以表示二维数组首元素的地址,
现在的首元素不是一个简单的整型元素,而是由4个整型元素组成的一维数组,
因此,a代表的是首行(即序列为0的行)的首地址,a+1代表序列为1行的首地址。
如果二维数组首地址为2000,一个整型数据占4个字节,则a+1的值应该是2000+4*4 = 2016(因为第0行有4个整型数据)。
a+1 指向 a[1],或者说 a+1的值是 a[1]的首地址。
a+2 的值代表 a[2]的首地址。
a[0],a[1],a[2]既然是一维数组名,而C语言又规定了数组名代表数组首元素的地址,
因此,a[0]代表一维数组a[0] 中第0列元素的地址,即 &a[0][0].
也就是 a[1] 的值是 &a[1][0],a[2]的值是&a[2][0].
a[0] 是一维数组名,那么一维数组中序号为1的元素的地址显然用a[0]+1 来表示了。
如果a[0] 的地址是2000,则a[0]+1 = 2000+1*4 = 2004
那么 a[0]+2 则应该等于 &a[0][2]
a[0] +3 = &a[0][3]
我们在前面提到过,a[0] 和 *(a+0)等价。
那么 a[1] 和*(a+1) 等价。
a[i] 和 *(a+i) 等价了。
因此 a[0]+1 和 *(a+0) + 1 都是&a[0][1]
二维数组中,第一维数组的值表示的是第二维数组的地址。
所以 a[1] +2 和 *(a+1)+2 的值都是 &a[1][2]
进一步分析,欲得到a[0][1] 的值,用地址法如何表示呢?
既然 a[0]+1 和 *(a+0)+1 是 a[0][1]的地址,那么*(a[0]+1) 就是 a[0][1]的值了,
同理,*(*(a+0)+1) 或 *(*a+1)也就是 a[0][1] 的值。
*(a[i]+j) 或 *(*(a+i)+j) 是a[i][j] 的值。。
*(a+i) 和 a[i] 是等价的。
#include <stdio.h> int main(){ int a[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23}; printf("%d,%d\n",a,*a); printf("%d,%d\n",a[0],*(a+0)); printf("%d,%d\n",&a[0],&a[0][0]); printf("%d,%d\n",a[1],a+1); printf("%d,%d\n",&a[1][0],*(a+1)+0); printf("%d,%d\n",a[2],*(a+2)); printf("%d,%d\n",&a[2],a+2); printf("%d,%d\n",a[1][0],*(*(a+1)+0)); printf("%d,%d\n",*a[2],*(*(a+2)+0)); return 0; }