二维数组的定义:

(以下数组没有申明的都为arr[3][3])

[3]={{1,2,3},{4,5,6},{7,8,9}};  要注意的是,红色框内的3表示列数,是不可省

略的,而前面框内的3是可以省略的。对于二维数组,定义方法和一维数组相似,区别在于二维数组有行列,所以定义时有两个[ ]

。同时,数组内每一个{ },表示的是一行,例如{1,2,3}表示的就是第一行的数据。而其中的1,2,3,则代表了这一行的第

一列,第二列和第三列数组。当然,定义二维数组时,数据也可以为空,例如:int arr[2][2]={};此时数组中的空项将都为0。

二维数组的传参:

      对于行列都知道的二维数组,传参可以用以下方式:

void Fun(int arr[3][3]){}

同样的,这里的行数(红色框内的)是可以省略的。

同时也可以用下面这样的方式传参:

void Fun(int (*arr)[3]){}

这里讲个别的方法,对于二维数组,是可以认为它是一个特殊的一维数组的,而在传参时,我们也可以将它看成是一个一维数组,写法如下:

void Fun(int *arr]){}

这边定义时和一维数组的方法是一样的,区别在与调用时,主函数要写为:Fun((int *)arr) 来进行调用

二维数组的访问:

printf("%d\n",arr);

对于二维数组arr,这段语句访问的将是arr的首地址,及arr[0][0]的地址。

arr+1:首地址+1,访问第二行的首地址,及arr[1][0]的地址,

arr[0]+1:访问第一行第二列的地址,及arr[0][1]的地址,

*(arr+1):访问第二行的首地址,及arr[1][0]的地址,

*(*(arr+1)):访问第二行第一列的数据,及arr[1][0]的值,

arr[1][0]:访问arr[1][0]的值,

&arr[1][0]: &取地址,所以这里访问arr[1][0]的地址,

*(arr+1)+2:访问第二行第三列的地址,及arr[1][2]的地址,这里可以分开看,*(arr+1)访问的是arr[1][0]的地址,在其地址上+2 ,得到的就是arr[1][2]的地址了,

*(arr[1]+2):访问第二行第三列的数据,及arr[1][2]的值,因为arr[1]+2是arr[1][2]的地址,对它解引用就是arr[1][2]的值,

*(*(arr+1)+2):访问arr[1][2]的数据,及arr[1][2]的值,和上面是一样的,只是不同的写法,arr[1]和*(arr+1)代表的都是arr[1][0]

的地址,

二维数组的内存存放:

二维数组在内存上存放和一维数组是一样的,不存在二维的存放,例如数组上第二行的数据就是跟在第一行后面存放的,所以对于二维数组,第二行第一列可以写成arr[1][0],也可以写成arr[0][4],这也就是为什么说二维数组是特殊的一维数组的原因。