二维数组传参 实例详解

无论 一/二维数组 传递参数本质 都是首地址的传送, 无法带下标传送,只能单独传送下标(下标本质就是地址偏移量),或约定下标长度! 一般数组 分配是在栈上进行的,能够保证所有元素的地址空间连续。 若使用malloc()在堆上分配空间,给数组则空间就不一定连续了

二维数组:在这里插入图片描述
下面以在默认栈中定义数组访问形式分析:
把它分为三大类:
第一类 固定 行列 传参 : 行列 固定
第二类 固定 列 传参; 行参数动态:列 固定,行做为参数动态
第三类 行列动态 传参:列行做为参数动态

是否可以 行列 都是动态,还不用传递行列形参,是否能做到呢? 答案:做不到。因为数组传递本质是指针参数传递,也就是地址传递。指针就是地址。传递过来的地址,是无法知道数组长度的。

第一类 固定 行列 传参

声明 / 定义形式

void Fun(int buf[2][3] ) //第一种 形参为数组
void Fun(int buf[ ][3] ) //第一种 形参为数组,可省略第一维,第二维就不可省略(由编译器的寻址方式决定第二维就不可省略)
void Fun(int (*buf)[3] ) //第二种 形参为数组指针,注意:不是(int *a[n])(指针数组) ,而是(int (*a)[n])(数组指针),因为 优先级: () 大于 [] 大于 * 

形参操作形式

buf[i][j] //访问的是 第 i 行 第 j 列
*(buf[i] + j) //同上
*(*(buf+i) + j) //同上
*((int *)buf + i*n +j) //同上,n表示第二维数组长度,即列宽

调用形式

Fun(ary); //void Fun(int buf[2][3] ); void Fun(int buf[ ][3] ); void Fun(int (*buf)[3] ) 的调用形式

示例代码:

#include <stdio.h>

//void Fun(int buf[2][3] ) //第一种 形参为数组
//void Fun(int buf[ ][3] ) //第一种 形参为数组,可省略第一维,第二维就不可省略(由编译器的寻址方式决定第二维就不可省略)
void Fun(int (*buf)[3] ) //第二种 形参为数组指针,注意:不是(int *a[n])(指针数组) ,而是(int (*a)[n])(数组指针),因为 优先级: () 大于 [] 大于 * 
{
	int i, j;
	
    for(i=0; i<2; i++)
	{
	    printf("buf[%d][0] = ", i);
        for(j=0; j<3; j++) 
    	{//四种操作形式
		    printf("%d ",  buf[i][j]);
		    printf("%d ",  *(buf[i] + j));
		    printf("%d ",  *(*(buf+i) + j));
		    printf("%d ",  *((int *)buf + i*3 +j));
        }
        printf("\r\n");
	}
}

void main()
{
    int ary[][3] = { {1, 2, 3}, {4, 5, 6} };
	int i, j;

	printf("\r\n数组传参数前:\r\n");
    for(i=0; i<2; i++)
	{
	    printf("ary[%d][0] = ", i);
        for(j=0; j<3; j++) 
    	{
		    printf("%2d ",  ary[i][j]);
        }
        printf("\r\n");
	}

	printf("\r\n数组传参数后:\r\n");
    Fun(ary);
}

运行结果:
在这里插入图片描述

第二类 固定 列 传参; 行参数动态

声明 / 定义形式

void Fun(int buf[2][3], int m) //第一种 形参为数组
void Fun(int buf[ ][3], int m) //第一种 形参为数组,可省略第一维,第二维就不可省略(由编译器的寻址方式决定第二维就不可省略)
void Fun(int (*buf)[3], int m) //第二种 形参为数组指针,注意:不是(int *a[n])(指针数组) ,而是(int (*a)[n])(数组指针),因为 优先级: () 大于 [] 大于 * 

调用,操作都是同第一类一样,只是行可变;

第一类 和 第二类 都是一个共同特点 第二维 不能省略, 也就意味着 第二维 (列) 不能动态 作为形参

第三类 行列动态 传参
**若 行列动态 / 列动态 怎么办?**有办法

声明 / 定义形式

void Fun(int **buf, int m) //第三种 形参为二级指针,m表示第一维数组长度,即行宽,列固定
void Fun(int **buf, int n) //第三种 形参为二级指针,n表示第二维数组长度,即列宽,行固定
void Fun(int **buf, int m, int n) //第三种 形参为二级指针,行列动态

形参操作形式

*((int *)buf + i*n +j) //同上,n表示第二维数组长度,即列宽, 只能这种操作

调用形式

Fun((int **)ary, m); //只能这样调用
Fun((int **)ary, n); //只能这样调用
Fun((int **)ary, m, n); //只能这样调用

代码示例:

#include <stdio.h>

void Fun(int **buf, int m, int n) //第三种 形参为二级指针
{
	int i, j;
	
    for(i=0; i<m; i++)
	{
	    printf("buf[%d][0] = ", i);
        for(j=0; j<n; j++) 
    	{
		    printf("%d ",  *((int *)buf + i*3 +j));
        }
        printf("\r\n");
	}
}

void main()
{
    int ary[][3] = { {1, 2, 3}, {4, 5, 6} };
	int i, j;

	printf("\r\n数组传参数前:\r\n");
    for(i=0; i<2; i++)
	{
	    printf("ary[%d][0] = ", i);
        for(j=0; j<3; j++) 
    	{
		    printf("%2d ",  ary[i][j]);
        }
        printf("\r\n");
	}

	printf("\r\n数组传参数后:\r\n");

    Fun((int **)ary, 2, 3);
}

运行结果:
在这里插入图片描述

  • 15
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值