【C语言】二维数组传参本质

本文详细解释了数组指针的概念,指出二维数组传参实际上是传递数组的首元素地址,即第一行的地址。并通过C语言示例展示了如何用指针形式接收和处理二维数组参数。
摘要由CSDN通过智能技术生成

二维数组传参本质

    • 1数组指针
      • 1.1什么是数组指针
      • 1.2数组指针变量初始化
    • 2.⼆维数组传参的本质

在探讨这个问题之前我们先了解一下数组指针变量

1数组指针

1.1什么是数组指针

数组指针是存放数组地址,能够指向数组的指针变量。

int (*p)[10];
  |   |   |
  |   |   p指向数组的元素个数
  |   p是数组指针变量名
   p指向的数组的元素类型
//类型为  int (*)[10]

p先和*结合,说明p是⼀个指针变量,然后指着指向的是⼀个⼤⼩为10个整型的数组。所以p是⼀个指针,指向⼀个数组,叫 数组指针。

注意:[]的优先级要高于* 号的,所以必须加上()来保证p先和*结合。

1.2数组指针变量初始化

数组指针变量是⽤来存放数组地址的,那怎么获得数组的地址呢?

&数组名

int arr[10] = {0};
&arr;//得到的就是数组的地址

调试后我们发现 &arr 和 p 的类型是完全⼀致的

在这里插入图片描述

2.⼆维数组传参的本质

有了数组指针的理解,我们就能够讲⼀下⼆维数组传参的本质了。

过去我们有⼀个⼆维数组的需要传参给⼀个函数的时候,我们是这样写的:

#include <stdio.h>
void test(int a[3][5], int r, int c)
{
 int i = 0;
 int j = 0;
 	for(i=0; i<r; i++)
 	{
 		for(j=0; j<c; j++)
 		{
 			printf("%d ", a[i][j]);
 		}
 		printf("\n");
 	}
}
int main()
{
 	int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};
 	test(arr, 3, 5);
 	return 0;
}    

这⾥实参是⼆维数组,形参也写成⼆维数组的形式,那还有什么其他的写法吗?

⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀行,是个⼀维数组。

在这里插入图片描述

所以,根据数组名是数组首元素的地址这个规则,⼆维数组的数组名表示的就是第⼀⾏的地址,是⼀维数组的地址。根据上面的例⼦,第一行的⼀维数组的类型就是 int [5] ,所以第一行的地址的类型就是数组指针类型 int(*)[5] 。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第一行这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下:

#include <stdio.h>
void test(int (*p)[5], int r, int c)
{
 int i = 0;
 int j = 0;
 	for(i=0; i<r; i++)
 	{
 		for(j=0; j<c; j++)
 		{
 			printf("%d ", *(*(p+i)+j));// *(*(p+i)+j)) 相当于 p[i][j]
//p, 此时的类型为int(*)[5] ,+i跳过 i*5*sizeof(int)个字节,所以这里跳过的是以一维数组大小为单位的,+1代表跳过第一行,+2跳过第一、二行
//*p,此时的类型为int[5], 变成一维数组的类型了,+j跳过j*sizeof(int)个字节
//*(*p),此时的类型变为int,也就访问到地址的内容,
 		}
 		printf("\n");
 	}
}
int main()
{
 	int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};
 	test(arr, 3, 5);
    //此处传递的是数组首元素地址,而二维数组首元素其实是第一行一维数组
    //因此在test函数中我们需要类型为 int(*)[5] 的指针变量来接收
 	return 0;
}

在这里插入图片描述

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值