C++语言-4-数组

本章学习数组的定义及使用方式。


数组,实际上就是一段连续的存储区间,概念上就是一个变量(元素)的集合。

以变量作为例子,每定义一个变量,就相当于为这个变量声明了一个存储空间,用来保存它的值。而当你声明了很多变量时,比如你声明了10个不同变量,那就在内存里占用了10个单位的存储空间。但是,如果你使用数组的话,声明长度为10的数组,也相当于占用了10个单位的存储空间,且是连续的,所以又叫存储区间。

语句就是:

类型 名称[长度];

如:

int a[10];

其中数组名称的命名要求也与变量一致。

设名称为a,长度为n,用一张表格来表示的话,就是下面这样。

a0 a1 a2 a(n-2) a(n-1)
值1 值2 值3 值n-1 值n

这样的一张表格,就表示一个数组。有0~n-1一共n个元素,每个元素对应一个值,并且每个元素都可以完全像变量一样使用。

也可以用一个0~n-1的整数坐标轴来表示,每个整数点上有一个值。

效果就相当于你定义了a0,a1,a2,…,an-1一共n个变量。

简单说,就是:

  1. 可以当做变量使用。
  2. 是一个有n个不同下标的元素的集合。

如上,这是一维数组。那么二维数组怎么表示呢?

int a[n][m];

这样就是定义了一个n*m个单位的二维数组。表格形式如下。

a 0 1 2 m-2 m-1
0
1
2
n-2
n-1

每个元素属于某一行某一列,设i表示行,j表示列,则当i和j确定时,所对应的元素唯一确定。

以此类推,还有三维数组,四维五维……不过常用的就是一维和二维了。

当一个数组定义后,我们可以通过“数组下标”来访问数组内的元素。所谓“数组下标”就是数组后中括号里填的东西。如,假设我们现在有一个定义:int a[100];则我们可以使用a[i]来访问a数组中下标为i的元素,i的范围为0-99。

发现了吧?假设数组被定义的长度为n,则可以使用的下标范围就是0~n-1,这正是上文中之所以写a0,a1,…,an-1的原因。这不以编程人员的意志为转移。哪怕你不使用下标为0的位置,它还是在那里,你最大可使用下标还是n-1。

所以,设有int a[100];则对于每一个a[i],都可以像普通变量一样使用。a[i]可以参与运算,也可以在等式左边来接受一个值。如int b=a[1];表示定义一个int类型变量b,并令其等于a数组第二个元素的值。同样的,也可以写a[10]=100;表示令a数组的第十一个元素的值等于100。

同理,对于二维数组,可以使用a[i][j]来访问a数组中第i行第j列的元素。两个维度的下标范围各自分离。如有int a[n][m];则在a数组中第一维下标范围为0~n-1,第二维的下标范围为0~m-1。二维数组的a[i][j],就如同一维数组的a[i],就如同普通变量,可以参与运算或在等式左边来接受一个值。

更多维数组可以以此类推。

但是数组只是定义的话,依然也是如同定义的变量一样,初始是未赋值状态。已知我们可以int a=0;来定义一个int类型的变量a,并对其赋初始值0。那么我们想对数组也进行每个位都赋初始值,该怎么做呢?可以写成如下形式:

int a[100]={0};

如上语句声明了一个int类型的数组a,有100个单位,将其每个单位都赋值为初始值0。

但要注意的是,如果想赋初始值1,这样写是不行的:

int a[100]={1};

这样将导致只有a[0]的值被初始化为1,其余位仍然都是0。

我们称这个1为显式指定的初始值。当使用大括号初始化时,数组会按顺序分配所有显式指定的初始值,而对没有显式指定的其余位置均分配为0。

例如,int a[100]={3,1,2,4};这样会按顺序令a[0]=3,a[1]=1,a[2]=2,a[3]=4,之后令其余位置均赋初始值为0。

所以,如果想全部初始化为1,则要么手写n个1在大括号里,要么用循环令a[i]=1。

而对于多维数组,我们则需要使用嵌套大括号。假设有int a[2][3];则可以以如下方式初始化:

1
int a[2][3]={{3,4,5},{1,2,3}};

因为数组第一维的容量是2,所以在最外层大括号中嵌套两层大括号,表示分别对第一维的每一行的三列进行初始化。而因为数组第二维容量是3,所以在每个第二级大括号里写3个数。

上述声明执行过后,会令a[0][0]=3,a[0][1]=4,a[0][2]=5,a[1][0]=1,a[1][1]=2,a[1][2]=3。
但其实写成这样:int a[2][3]={3,4,5,1,2,3};结果也与上述写法相同,只是对于人类来说没有那么直观。

为什么会一样呢?因为数组内部在分配顺序的时候,是从最后一维开始分配的,比如有三维数组a[2][2][2],则顺序是a[0][0][0],a[0][0][1],a[0][1][0],a[0][1][1],a[1][0][0],a[1][0][1],a[1][1][0],a[1][1][1]。可见,顺序的规则是恒定不变的,需要的是程序员来调整初始化数值的顺序。

需要注意的是,如果不采用嵌套大括号,则必然是按顺序初始化。而采用嵌套大括号的话,可以按需求针对不同维度进行初始化。示例如下:

假设有二维数组:

1
int a[4][4];

则我可以写:

1
int a[4][4]={{0,1,1},{1,2},{3,1,4,5},{6}};

进行初始化。初始化的结果为:

1
2
3
4
a[0][0]=0,a[0][1]=1,a[0][2]=1
a[1][0]=1,a[1][1]=2
a[2][0]=3,a[2][1]=1,a[2][2]=4,a[2][3]=5
a[3][0]=6

其余单位因为没有显式指定而均为0。

第四章到此结束。

本章练习:

P1046 陶陶摘苹果

P1427 小鱼的数字游戏

P1428 小鱼比可爱

P1567 统计天数

P1047 校门外的树

P2141 珠心算测验

--It's the end.Thanks for your read.--