二维数组传参与动态声明详解

本文详细探讨了二维数组在C语言中的传参形式,包括基本形式、数组传参形式、动态数组形式和折中形式。文章指出,二维数组在栈上的分配会导致地址空间连续,而在函数参数中使用指针形式时,需要考虑如何正确解引用。同时,文章介绍了使用malloc在堆上动态分配二维数组的方法,以及C99中对动态二维数组的支持。最后,作者强调了不同类型二维数组在函数传参中的差异,并给出了相关的C++动态分配和STL容器vector的使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二维数组传参

基本形式

二维数组在栈上分配,各行地址空间连续

定义的时候,拥有两种形式

第一种是指明行数和列数

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+ii实际上偏移了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。那么,为了指导这个函数如何解引用,也就是人为地解引用,需要把这个二维数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值