1、在讲二维数组之前,我们先搞清楚一些基本的概念:
1)、数组名代表的是数组首元素的地址,这是一个常量。即数组已经定义,它的含义便已经明确了,数组就是一个固定内存块大小的别名
2)、数组首元素的地址和数组的地址是不同的东西
3)、数组也是一种数组类型,其类型由构成数组的元素的类型和数组的大小一起决定
现在对上面所提到的内容进行一下详细的解释:
看一个例子
我们可以看到,数组一经定义,不管有没有显示初始化,其所指向的内存空间便已经定了下来。
我们都知道,数组一经定义,其大小便确定下来了,所以我们直接用sizeof(array_int1)来得到数组的大小,经过测试,sizeof(array_int1) = 40;
现在再求sizeof(&array_int1),可以得到sizeof(&array_int1) = 4。为什么会时上面的结果呢?
上面说了,数组类型是由构成数组的元素的类型和数组的大小一起决定。例如:int array_int1[10],便是代表一种int [10] 的数据类型, 同理 float f_float1[12] 便是代表一种float [12]的数据类型。既然是这样,我们便可以定义一个数组类型,使用typedef ,例如 typedef int (array_int)[5], typedef double (ayyay_double)[4] 。
很明了吧,有一点需要注意的就是,在定义一种数组类型的时候,数组名一定要括起来,这种定义的方法可能和其他的typedef不大一样。或许你还想知道,这样的类型有什么用,不要着急,后面会讲到的,现在我们先把上面的问题完成了再说。
既然明白了数组类型了,那我们就能够明白为什么sizeof(array_int1) = 40 ,而 sizeof(&array_int1) = 4。这是因为,变量array_int1是一种int [10]的数据类型,那么&array_int1便是对这个变量求地址了,并且,在32位系统下,不管是内置类型还是自定义类型,对该类型的变量求地址后用sizeof() 运算符,得到的都是4。
2、二维数组的定义和初始化
二维数组的定义和初始化和一维数组类似,这里不再多说。值得注意的有两点:
1)、任何数组初始化的时候不能初始化为空; int a[10]; a[10] = {};//这是错误的,因为不能将数组指向一块不存在的内存空间
2)、在使用多维数组时,我们要把多维数组当做是数组的数组。
3、二维数组的下标访问以及二级指针的操作
二维数组的下标操作符和一维数组的没有区别,理解的时候需要记住,a[8] = *(a+8)。
二维数组在上述基础上,我们可以用多种方式来访问二维数组了。
#include <iostream>
using namespace std;
#define PI 3.14
//初始化数组
void Init_Int_Array(int (*p)[4]);
void Init_Double_Array(double array[2][3]);
void Display_Int_Array(int (*array)[4]);
void Display_Double_Array(double array[][3]);
int main()
{
int array_int[3][4];
double array_double[2][3];
int (*pint)[4] = array_int;
double (*pdb)[3] = array_double;
Init_Int_Array(pint);
Init_Double_Array(pdb);
Display_Int_Array(pint);
Display_Double_Array(array_double);
return 0;
}
void Init_Int_Array(int (*p)[4])
{
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
p[i][j] = i*j;
}
}
void Init_Double_Array(double array[2][3])
{
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
*(*(array+i)+j) = PI*i*j;
}
}
void Display_Int_Array(int (*array)[4])
{
for(int i = 0;i<3;i++)
{
for(int j=0;j<4;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
void Display_Double_Array(double array[][3])
{
for( int i = 0; i <2;i++)
{
for(int j=0;j<3;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
以下是程序运行的结果:
上述例子中提供了多种访问二维数组的方法,整个程序如果详细讲解的话过于累赘,我只介绍一下二维数组的遍历,其他地方如果还有什么不懂的地方可以相互交流。
1)、这种遍历方式( p[i][j] = i*j; )想必大家都懂,
2)、 *(*(array+i)+j) = PI*i*j;//主要是这种方式。
在一维数组中已经讲了数组遍历的两种方式,(*a+6) = a[6];。还有一个就是二维数组中的每一行也是一个数组。
对于array[3][4]而言,每一个array[i]都是一个有四个元素构成的数组,而array[i]可以表示成 *(array +i),所以 array[i][j] 便可以表示成 *(*(array+i)+j)
初次接触或是对指针等的了解不深的话可能对上述的操作有些疑问,下面我将数组做函数参数和指针之间的对应关系给大家讲解一下:
一维数组当然对应一维指针:
int a[10] ;要将数组作为实参,则形参中应该写成这样 int * p;
二维数组需要二维指针:
char ch[10][20];要将数组作为实参,则形参中应该按照下面的方式来写 ch (*pch)[20];//注意,形参中(*pch) 的括号不能少,[]中的数字必须要和实参中的对应
至于还有的一种方法 char ch[][20]或是char ch[10][20],这样写并没有错,只是在程序书写中显得并不是特别的规范,所以尽量不要采用。
本文详细介绍了C++中的二级指针和二维数组,包括基本概念、定义与初始化、下标访问及操作。通过示例解析了二维数组的遍历方式和作为函数参数时的对应关系,帮助读者深入理解指针与数组的交互。

1112

被折叠的 条评论
为什么被折叠?



