C语言:传递二维数组参数(固定维度和不固定维度两种)

前言:
今日做一道dp的题,然后需要二维dp,我本人觉得用vector的二维数组会耗时长(毕竟类对象,肯定比基本数组类型的二维数组慢),所以打算使用int dp[][],然而遇到点麻烦,解决如下。


二维数组的定义:
二维数组的说法是不准确的,因为C/C++都不存在二维数组的数据结构,只不过一些入门教程为了让初学者快速理解产生的名词,所以在C/C++仅存在数组的数组的说法。二维数组的地址存储方式讲的很清楚,可以看看。


二维数组作为函数参数传递的方法:

1)固定维度的方法:

1.1)形参需给出数组的两个维度,当然第一个维度可以忽略。如果不指定维度就会出错,因为编译器只知道数组传来起始地址,不知道列数,这样导致无法确定元素位置:

int nums[3][4]={0}

/*给出数组的两个维度*/
void func_1(int nums[3][4]);
func_1(nums);

/*形参可以只指定为数组的第二维长度*/
void func_2(int nums[][4]);
func_2(nums);

1.2)形参声明为指向数组的指针,注意*与变量要用(*num)括号括起来(否则由于[]的优先级比*高,这样就会生成指针数组了,即数组里面为int*类型的指针):

int nums[3][4]={0};
/*指向数组的指针*/
void func(int (*num)[4]);
func(nums);

2)不固定维度的方法:

2.1)将二维数组当一维数组操作,因为二维数组在栈区就是一块连续的内存,dp表示第一个元素的地址,dp+1表示第二个元素的地址,dp+i*n+j表示第(i+1)*n+j+1个元素的地址,对应二维数组中的坐标[i,j]的地址。也就是说,要想访问元素的值我们需要手工寻址,测试代码如下:

注:这里的数组属性退化成了二级指针的属性,因此这里并不能使用nums[i][j]这种方式来进行数组取值,因为指针没有重载operator[]

#include <iostream>
using namespace std;

void testArray(int* dp,int m,int n)//m为行数,n为列数
{
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j){
            cout<<*(d+i*n+j)<<" ";//手工寻址
        }
        cout<<endl;
    }    
}

int main()
{
    int dp[3][2]={{1,2},{3,4},{5,6}};
    testArray(*dp,3,2);//这里传递的一维数组的首元素地址
    return 0;
}

2.2)直接用二级指针来传递二维数组形参,注意这里地址类型都要进行类型转换,否则编译器就会报错:

#include <iostream>
using namespace std;

void testArray(int** d,int m,int n)
{
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j){
            cout<<*((int*)d+i*n+j)<<" ";//d需要类型转换为int*,这样表示一维数组
        }
        cout<<endl;
    }    
}
int main()
{
    int dp[3][2]={{1,2},{3,4},{5,6}};
    testArray((int**)dp,3,2);//dp需要进行类型转换
    return 0;
}
  • 11
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值