数组
在本节课中,我们将讨论数组,如何声明数组以及如何访问数组中的数据。
如果需要五个不同的值来进行计算,我们必须将这些值存储在五个不同的变量中。这五个变量的声明如下:
1double value_1; 2double value_2; 3double value_3; 4double value_4; 5double value_5;
这种逐个定义变量的方法在需要更多变量时无法扩展。试想一下,如果需要一千个值,从 value_1 到 value_1000 逐一定义几乎是不可能的。
此时数组就非常有用:数组功能允许我们定义一个单一变量,用来一起存储多个相同类型的值。虽然简单,但数组是存储一组值最常用的数据结构。
本章仅介绍数组的部分特性,更多内容将在后续的“切片及其他数组特性”课程中讲解。
定义
数组变量的定义方式与普通变量非常相似,唯一的区别在于用方括号指定了变量关联的值的数量。我们可以对比如下两种定义方式:
1int singleValue; 2int[10] arrayOfTenValues;
第一行是定义一个仅存储单个值的变量,就像我们之前定义的所有变量一样。第二行是定义一个存储十个连续值的变量,换句话说,它是一个包含十个整数值的数组。你也可以将其理解为定义了十个相同类型的变量。
因此,上述五个独立变量的等价形式可以使用以下语法定义为一个包含五个值的数组:
1double[5] values;
该定义可读作“五个双精度浮点值”。注意,我选择将数组变量命名为复数形式,以避免与单值变量混淆。仅存储单个值的变量称为标量变量。
总结来说,数组变量的定义由三部分组成:值的类型、值的数量以及指向该值集合的变量名称:

值的类型也可以是用户自定义类型。例如:
1/* 一个存储所有城市天气信息的数组。其中布尔值表示: 2false:多云 3true:晴天 4*/ 5bool[cityCount] weatherConditions; 6 7// 一个存储一百个箱子重量的数组 8double[100] boxWeights; 9 10// 学校学生信息 11StudentInformation[studentCount] studentInformation;
容器与元素
将某种类型元素组合在一起的数据结构称为容器。根据此定义,数组就是一种容器。
示例
考虑一个存储七月份每日气温的数组,它可以包含31个双精度浮点值,构成一个类型为 double 的元素容器。
容器中的变量称为元素。数组中元素的数量称为数组的长度。
访问元素
为了区分前面课程中定义的各个变量,我们在它们的名字后添加了下划线和数字,如 value_1。但在一个数组中,所有值都通过同一个名字存储时,这种做法既不可行也不必要。相反,我们通过在方括号中指定元素编号来访问元素:
1values[0]
这个表达式可以理解为名为 values 的数组中编号为 0 的元素。这里的 0 可以看作第一个元素的索引。换句话说,使用数组时,不应输入 value_1,而应输入 values[0]。
这里有两点非常重要,值得强调:
- 索引从零开始:尽管人类通常从 1 开始给物品编号,但数组中的索引从 0 开始。我们之前编号为 1、2、3、4、5 的值,在数组中分别对应索引 0、1、2、3、4。这一差异常常让初学者感到困惑。
[]符号的两种不同用途:不要混淆[]的两种不同用法。在定义数组时,[]写在元素类型之后,用于指定元素数量;在访问元素时,[]写在数组名之后,用于指定要访问的元素编号:
1// 这是定义。它定义了一个包含12个元素的数组,用于存储每个月的天数。 2 3int[12] monthDays; 4 5// 这是访问。它访问对应十二月的元素,并将其值设为31。 6 7monthDays[11] = 31; 8 9// 这是另一处访问。它访问对应一月的元素,并将该值传递给 writeln。 10 11writeln("一月有 ", monthDays[0], " 天。");
提醒:一月和十二月的元素索引分别是 0 和 11,而不是 1 和 12。
索引
数组中元素的位置称为其索引,访问元素的操作称为索引。
索引不必是常量;变量的值也可以作为索引,这使得数组更加灵活。例如,下面的 monthIndex 变量的值可以决定当前是哪个月:
1int monthIndex = 2; 2writeln("这个月有 ", monthDays[monthIndex], " 天。");
当 monthIndex 的值为 2 时,上述表达式将打印 monthDays[2] 的值,即三月的天数。
只有介于 0 到数组长度减一之间的索引才是有效的。例如,一个三个元素的数组的有效索引是 0、1 和 2。访问无效索引会导致程序终止并报错。
数组是一种容器,其元素在计算机内存中是连续排列的。例如,存储每月天数的数组元素可以如下所示(假设二月有28天):
注意:上述索引仅用于演示目的,实际并不存储在计算机内存中。
索引 0 的元素值为 31(一月天数),索引 1 的元素值为 28(二月天数),依此类推。
固定长度数组与动态数组
如果数组长度在编写程序时就已经确定,则该数组为固定长度数组。固定长度数组也称为静态数组。如果数组长度可以在程序运行期间改变,则该数组为动态数组。
到目前为止我们定义的数组都是固定长度数组,因为它们的元素数量在编写程序时就已经指定,运行期间无法更改。若需修改长度,必须修改源代码并重新编译程序。
定义动态数组比定义固定长度数组更简单,只需省略长度即可:
1int[] dynamicArray;
这样的数组在程序运行期间可以动态增加或减少长度。
使用 .length 获取或设置元素数量
数组也有属性。目前我们只关注 .length 属性。.length 返回数组的元素数量:
1writeln("该数组有 ", array.length, " 个元素。");
此外,动态数组的长度可以通过向该属性赋值来更改:
1import std.stdio; 2 3void main() { 4 int[] array; // 初始为空 5 array.length = 5; // 现在有5个元素 6 writeln(array.length); 7}
在下一课中,我们将看到一个简单的数组应用场景,展示数组的重要性。