写在前面:
今天为什么要把“二维数组”这个概念重新拎出来说一说呢。原因是这样的:前几天在用c++写银行家算法的时候,resource类的成员变量有二维数组,开始写的是默认初始化的方式,类似于这种:
class A
{
...
privated:
arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
}
结果报错。所以就想重新写个成员函数用来初始化二维数组,结果没想到这个时候脑子居然乱套了,形参在用一级指针还是二级指针陷入了纠结与痛苦中 ̄□ ̄|| 于是说想写一篇文章,把C语言和c++相关的二维数组需要注意的方方面面都拎出来说一下。一方面也是自己的巩固,另一方面也欢迎大家的补充和指正。
目录
1.二维数组的初始化;
2.二维数组在内存中的存储情况;
3.二维数组的函数调用方式;
4.如何动态的申请二维数组;
5.扩展:三维数组
1.二维数组的初始化
例如对整型二维数组a[3][2]赋值
方法一:
在定义的同时赋值
int a[3][2]={0};//所有数组元素均为0
方法二:
int a[3][2]={1,2,3,4,5,6};//常规的赋值方法
方法三:
int a[3][2]={{1,2},{3,4},{5,6}};//分行的赋值方法
方法四:
int a[3][2]={{1,2},{0},{3}};//部分赋值方法,第一行元素的值分别为1,2,第二行元素值都是0,第三行第一个元素值为3,第二个元素值为0
方法五:
int a[3][2]; //先定义
for(i=0;i<=3;i++) //用双重for循环赋值,i,j表示二维数组下标
for(j=0;j<=2;j++)
scanf("%d",&a[i][j]);
2.二维数组在内存中的存储情况
通过上边的图片,我们应该能够认识到,二维数组arr[3][4]可以这么理解:
这是一个包含3个元素的一维数组,而这个一维数组的每一个元素又都是一个一维数组.存储方式也类似一维数组:线性存储。
int [][]arr=new int[3][]; //定义了一个二维数组,该数组里有三个一维数组;
//int [][] 是arr的类型
3.二维数组的函数调用方式
我们知道数组名就等于数组首元素的地址;函数传参的时候,数组会退化为指针;
类比一维数组的调用:
void init(int *arr,int size)//也可以直接用一维数组接收,数组会
//退化为指针:void init(int arr[],int size)
{
int i=0;
for(i=0;i<size;++i)
printf("%d",*arr); //也可以写成 printf("%d",arr[i]);
}
int main()
{
int arr[3];
int size=sizeof(arr)/sizeof(arr[0]);
init(arr,size);
}
二位数组除了形参用二位数组接收之外,还可以这么写:
运行结果:
4.如何动态的申请二维数组的空间
我们知道一维数组的动态申请:
int *arr=new int[3];
动态申请一个二位数组:
//动态申请一个M*N的二维数组
int **p = new int*[M];
for (i = 0; i<M; ++i)
{
p[i] = new int[N];
}
5.扩展:三维数组
类比于二位数组,三维数组arr[2][2][2]我们可以想象有一个一维数组,它每一个元素(一共2个元素,看第一个2)都是一个二位数组;
static int a[2][2][2]={ { {1,2} , {3,4} } , { {5,6} , {7,8} } };
分开来讲是这样:先看最高维:把{{1,2} , {3,4}}给a[0], {{5,6} , {7,8}}给a[1]相当于:
a[0]={{1,2},{3,4}};
a[1]={{5,6},{7,8}};
把一个二维的数据赋给二维的变量,现在不难理解了吧。