前言:
今日做一道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;
}