为什么要使用数组?

我们先举一个例子,打印班里学号1-5同学的语文成绩。

1
2
3
4
5
6
7
8
9
#include<iostream>
using namespace std;

int main(){
    int y1, y2, y3, y4, y5;
	cin >> y1 >> y2 >> y3 >> y4 >> y5;
    cout << y1 << y2 << y3 << y4 << y5;
    return 0;
}

从上面的例子可以看出来,想要处理5名同学的语文成绩,就要定义5个变量,用cin输入时,要写5个变量,输出时也一样。我们再设想一下,如果处理全班40个同学的成绩呢?全校400个同学的成绩呢?全市4000个同学的成绩呢?即使这么简单的问题,我们都无法完成编写代码。

那计算机能不能实现处理4000个同学的成绩呢?当然可以。对于计算机来说,都是小意思。这就要引入一个新的概念–数组。

什么是数组?

在前面介绍数据类型的时候,已经说过:要想把数据放入内存,必须先要分配内存空间。放入5个整数,就得分配5个int类型的内存空间:

1
int a[5]

按照上述方式声明后,就在内存里面开辟了5个内存空间,用来存放5个int类型的数据,并给它命名为a。

这样的一组数据的集合,我们就叫作数组,它包含的每一个数据叫作数组元素,所包含的数据个数叫作数组长度。上面我们定义的数组a,长度为5。

数组中的每个元素都有一个编号,叫作下标。数组的下标是从0开始的,从0开始的,从0开始的,重要的事情说三遍。要使用数组里面的元素,指明下标即可。如,想要得到数组a中的第一个元素,则:

1
a[0]

再强调一遍,数组的第一个元素是a[0],不是a[1]

下面重新来写一下,文本开始的例子。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include<iostream>
using namespace std;

int main(){
    int y[5];
    for(int i = 0; i < 5; ++i)
		cin >> y[i];
    for(int i = 0; i < 5; ++i)
    	cout << y[i];
    return 0;
}

这样的话,处理几千甚至几万个同学的成绩都能轻松完成。变量 i 既是数组下标,也是循环条件;将数组下标作为循环条件,达到最后一个元素时就结束循环。数组y 的最大下标是 4,不能超过5,所以我们规定循环的条件是 i<5,一旦 i 达到5 就得结束循环。

数组的内存空间是连续的

数组是一个整体,它的内存空间是连续的;也就是说,数组元素之间在内存中是相互挨着的,彼此之间没有一点点缝隙。下图演示了int y[5];在内存中的存储情形:

y[0] y[1] y[2] y[3] y[4]

数组内存空间是连续的”这一点很重要,所以,再次强调一下。连续的内存为指针操作(通过指针来访问数组元素)提供了便利。大家暂时还不理解这句话是什么意思,后边学了指针自然就明白了。

数组的初始化

上面的例子是先定义数组,再逐个输入成绩,给数组赋值。我们也可以在定义数组的时候,同时进行赋值,数组元素的值由{ }包围,各个值之间以,分隔。如:

1
int y[5] = {98, 95, 93, 100, 90}

注意

  1. 可以只给部分元素赋值。当{ }中值的个数少于元素个数时,只给前面部分元素赋值,剩余的元素自动初始化为 0:

    • 对于short、int、long,就是整数 0;
    • 对于char,就是字符 ‘\0’;
    • 对于float、double,就是小数 0.0。
  2. 只能给元素逐个赋值,不能给数组整体赋值。例如给 10 个元素全部赋值为 1,只能写作:

    1
    
    int a[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    

    而不能写作:

    1
    
    int a[10] = 1;
    
  3. 如给全部元素赋值,那么在定义数组时可以不给出数组长度。例如:

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

    等价于

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

公众号:格致书院