二维数组传参
基本形式
二维数组在栈上分配,各行地址空间连续
定义的时候,拥有两种形式
第一种是指明行数和列数
int array[3][3] = {
{1,2,3},{4,5,6},{7,8,9}};
第二种是不指明第一维,而指明第二维
int array[][3] = {
{1,2,3},{4,5,6},{7,8,9}};
而在子函数声明的时候,有三种方式
一种是指明形参的行数和列数
int func(int array[][3], int m, int n) {
int i,j;
for(i=0;i<m;i++) {
for(j=0;j<n;j++)
//printf("\t%d", *(*(array +i) +j)); //可行
printf("\t%d", array[i][j]);
printf("\n");
}
return 0;
}
第二种是不指明形参的第一维,而指明第二维
int func(int array[][3], int m, int n) {
int i,j;
for(i=0;i<m;i++) {
for(j=0;j<n;j++)
//printf("\t%d", *(*(array +i) +j)); //可行
printf("\t%d", array[i][j]);
printf("\n");
}
return 0;
}
第三种是形参使用指针的形式,
int func(int (*array)[3], int m, int n) {
int i,j;
for(i=0;i<m;i++) {
for(j=0;j<n;j++)
//printf("\t%d", *(*(array +i) +j)); //可行
printf("\t%d", array[i][j]);
printf("\n");
}
return 0;
}
而定义的两种形式与调用的三种形式是可以互相混合使用,因此基本形式一共有2x3=6
中方法
运行结果均为:
这种分配是在栈上进行的,能够保证所有元素的地址空间连续。这样,array[i][j]
和 *(*(array +i) +j)
是一样的,**程序是知道array+i
的i
实际上偏移了i*N
个单位,**这也导致了在二维数组array[3][3]
中,使用下标array[2][1]
和array[1][4]
是访问的同一个元素,尽管后者的下标对于一个3*3
矩阵来说是非法的,但这并不影响访问。
这种形式,无论是数组定义还是函数都不够泛用,两个维度在编译前就定好了,唯一可以做的就是把维度M、N
声明为宏或者枚举类型,但这仍不能避免每次修改后都要重新编译。
**注意:**在主函数中调用子函数的方法与在子函数中访问数组的方法
在主函数中调用子函数
func(array,m,n);
在子函数中使用形参数组有两种方式
array[i][j]
和 *(*(array +i) +j)
数组传参形式
二维数组在栈上分配,各行地址空间连续,函数参数使用指针形式
当把这种二维数组的指针直接作为参数传递时,数组名退化为指针,函数并不知道数组的列数,N
对它来说是不可见的,即使使用*(*(array +i) +j)
,第一层解引用失败。这时,编译器会报warning,运行生成的文件会发生segment fault。那么,为了指导这个函数如何解引用,也就是人为地解引用,需要把这个二维数组