(一)二维数组初始化
二维数组初始化分为多种形式。注意,当只对部分元素赋初值时,对于int型数组,未赋初值的元素自动取0值。
1)按行赋值
int a[ ][3]={{1,2,3},{4,5,6}};}
int a[ ][3]={{1,2},{0}}; 相当于{{1,2,0},{0,0,0}}
2)连续赋值
int a[ ][3]={1,2,3,4,5,6};
——相当于{{1,2,3},{4,5,6}}
int a[ ][3]={2};
——相当于{{2,0,0}}
另外,对于第一维的维度不写的,则根据“「元素的个数/列数「”(上取整)来确定行数。
快速将数组初始化为0 , 可使用memset(array, 0 , sizeof(array)); memset是内存操作,作用是设置每一个“字节”的值
3)二维数组一维化
利用一个数组的访问方式来访问二维数组。
int iArr[2][3]={0,1,2,3,4,5};
可以用一个指向int型的指针变量来访问这个数组,下面的代码是将数组一维化:
int* p = iArr[0];
上面的iArr[0]就是代表第一个数组的首地址(iArr也代表第一个数组的首地址,但是并不占用内存,只是一个名字),由于二维数组在内存中的存储也是先行后列的方式,所以第二行也紧跟第一行之后,这样就可以用p来访问数组的元素值了,访问的方式有下标和指针方式。
printf("%d,",p[3]);
printf("%d\n",*(p+3));
最后输出的结果都是3
(二)关于二维数组名
可能想当然的话,二维数组不就是一个二级指针吗?真是这样吗?下面用代码来验证下:
int iArr[2][3]={0,1,2,3,4,5};
int **pp = iArr;
会出现下面的编译错误:“初始化”: 无法从“int [2][3]”转换为“int **”
其实二维数组名是一个数组指针,数组指针是指向一个数组首地址的指针,它实际上也是一种指针类型,类似于函数指针。它声明如下:
int (*pArr)[3] ;
它说明pArr是一个数组指针,它是指向(一个数组元素为int类型并且数组元素的个数为3的一个数组)的首元素地址的指针。 既然二维数组的数组名是指向第一行数组的首地址,我们也叫它行指针。那么我们可以用这种数组名或者指针来访问二维数组的元素。
int (*pArr)[3] = iArr;
下面,我要访问第一行第二列的元素,我可以用下面的代码来访问
*(*(pArr+1) + 2)
也可以用数组名来访问:
*(*(iArr+1) + 2)
首先,pArr是一个指向数组的指针,在这个指针上加减一个整数都是移动整行,而不是一个元素。比如说,pArr+1代表的现在指针已经指向第一行元素了,也就是实际中的第二行,而要取得指针所指的对象,就要用到解引用运算符*,所以*(pArr+1)就代表第一行数组,是整个这一行元素就取到了,那现在要取这一行的第二个元素,只须将指针再移动两个元素,即*(iArr+1) + 2,这样就指向了这个元素的地址,再解引用取得元素的值即可。
(三) 二维数组做函数参数
(1)参数是二维数组,但是要指定第二维的维数。
int array[10][10];
函数声明:void fuc(int array[][10]);
函数调用:fuc(array);
(2)参数使用一维指针数组
int *array[10];
for(i = 0; i < 10; i++)
array[i] = new int[20]; //******** 重要 array[i]是int型指针,这里给array[i]指针初始化了20个int型空间。
函数声明:void fuc(int *a[10]);
函数调用:fuc(array);
——在函数fuc中,a是一维指针数组。使用*(a[i] + j)形式来访问数组中元素。
注意: int *a[10] 和 int (*a) [10] 的区别!!!!!!!!!!!
int *a[10] :指针数组,数组a里存放的是10个int型指针。 识别方法:先找到声明符a,然后向右看,有[]说明a是一个数组,然后再向左看,有int *, 说明数组中的每个元素都是int *。 所以是存放int指针的数组。
int (*a)[10]:数组指针,a是指针,即数组首元素地址的指针,此数组里面有10个int型元素。识别方法: 先找到声明符a,然后又括号,优先级高,先向右看,没东西,然后向左看,有*,说明a是一个指针,然后跳出括号,向右看[],说明a指针指向了一个数组,然后向左看int, 说明数组中存放的是int型。
int *p[10];
int (*q)[10];
printf( "*p[10]: %d\n ", sizeof(p));
printf( "(*q)[10]: %d\n ", sizeof(q));
结果是:
*p[10]: 40 //说明p是一个数组名
(*q)[10]: 4 //说明q是一个指针
(3)参数使用指针的指针。
int **array;
array = newint *[10];
for(i = 0; i <10; i++)
array[i] = new int[20]; //array[i]即指上面的指针数组。
函数声明:void fuc(int **a);
函数调用:fuc(array);
——在函数fuc中, a是指针的指针。使用array[i][j] 或 *(int *)(a + (i-1)*d2 + j)形式来访问数组中元素(d2为二维数组的二维维数,即列数。并且a + (i-1)*d2 + j为地址,所以要把这个类型为指针的指针的地址强制转换为指针来使用。)。其中:
a[0]<=>array[0][0],
a[1]<=>array[0][1],
…
a[10]<=>array[1][0]