C语言二维数组与二维指针
近期通过一道例题,我总结了一下二维数组、二维指针、二维数组首地址三者之间的关系,请网友多多批评指点。
例题
错误的代码
#include<stdio.h>
#include<stdlib.h>
int fun(int arr[5][5])
{
int sum=0,i;
for(i=0;i<=4;i++)
{
sum+=arr[i][i];sum+=arr[4-i][i];
}return sum;
}
int main()
{
int i,sum=0;
int** arr=(int**)malloc(5*sizeof(int*));
for(i=0;i<=4;i++)
{
arr[i]=(int*)malloc(5*sizeof(int));
}
for(i=0;i<=4;i++)
{
scanf("%d %d %d %d %d",&arr[i][0],&arr[i][1],&arr[i][2],&arr[i][3],&arr[i][4]);
}
int a=fun(arr);
printf("sum=%d\n",a);
for(i=0;i<=4;i++)
{
free(arr[i]);
}free(arr);
}
错误原因
没有理解形参列表中int arr[5][5]的意义,如果函数声明时形参是int fun(int arr[5][5]),那么说明调用fun函数的时候应该给一个5行5列的二维数组第一个元素的地址作为参数,这5行5列共25个数据的地址是连续分布的。
但是在上述程序中,主函数里的arr是我用malloc命令在堆区创建的。arr不能称作是某一个二维数组的首地址。严格来说arr只是一个一维数组的首地址,而这个一维数组是由5个指针类型的变量组成的,每个指针类型的变量是一个包含5个int类型数据的一维数组的首地址。因此,arr因为数据类型不同,不能传给int fun(int arr[5][5])做参数。
正确的代码
问题的根源在于形参与实参的数据类型不匹配,解决方案是统一形参与实参的数据类型。要么形参和实参都是二维数组的首地址,要么形参和实参都是二维指针。
方案一
#include<stdio.h>
#include<stdlib.h>
int fun(int arr[5][5])
{
int sum=0,i;
for(i=0;i<=4;i++)
{
sum+=arr[i][i];sum+=arr[4-i][i];
}return sum;
}
int main()
{
int i,sum=0;
int arr[5][5]={{0,0,0,0,0},{1,1,1,1,1},{2,2,2,2,2},{3,3,3,3,3},{4,4,4,4,4}};
for(i=0;i<=4;i++)
{
scanf("%d %d %d %d %d",&arr[i][0],&arr[i][1],&arr[i][2],&arr[i][3],&arr[i][4]);
}
int a=fun(arr);//二维数组的数组名即为二维数组的首地址
printf("sum=%d\n",a);
}
方案二
#include<stdio.h>
#include<stdlib.h>
int fun(int** arr)
{
int sum=0,i;
for(i=0;i<=4;i++)
{
sum+=arr[i][i];sum+=arr[4-i][i];
}return sum;
}
int main()
{
int i,sum=0;
int** arr=(int**)malloc(5*sizeof(int*));
for(i=0;i<=4;i++)
{
arr[i]=(int*)malloc(5*sizeof(int));
}
for(i=0;i<=4;i++)
{
scanf("%d %d %d %d %d",&arr[i][0],&arr[i][1],&arr[i][2],&arr[i][3],&arr[i][4]);
}
printf("sum=%d\n",fun(arr));
for(i=0;i<=4;i++)
{
free(arr[i]);
}free(arr);
}