C语言二维数组与二维指针

C语言二维数组与二维指针

近期通过一道例题,我总结了一下二维数组、二维指针、二维数组首地址三者之间的关系,请网友多多批评指点。

例题

Alt

错误的代码

#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);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值