二维数组的定义:
(以下数组没有申明的都为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],这也就是为什么说二维数组是特殊的一维数组的原因。