C/C++二维数组的相关总结(扩展:三维数组)

写在前面:

今天为什么要把“二维数组”这个概念重新拎出来说一说呢。原因是这样的:前几天在用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.二维数组在内存中的存储情况
C/C++二维数组的相关总结(扩展:三维数组)
通过上边的图片,我们应该能够认识到,二维数组arr[3][4]可以这么理解:
这是一个包含3个元素的一维数组,而这个一维数组的每一个元素又都是一个一维数组.存储方式也类似一维数组:线性存储。

int [][]arr=new int[3][]; //定义了一个二维数组,该数组里有三个一维数组;
                         //int [][]   是arr的类型

3.二维数组的函数调用方式
(1)





(2)我们知道数组名就等于数组首元素的地址;函数传参的时候,数组会退化为指针;
类比一维数组的调用:


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);
}

二位数组除了形参用二位数组接收之外,还可以这么写:
C/C++二维数组的相关总结(扩展:三维数组)
C/C++二维数组的相关总结(扩展:三维数组)
运行结果:
C/C++二维数组的相关总结(扩展:三维数组)
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}};
把一个二维的数据赋给二维的变量,现在不难理解了吧。