4.1.2 声明数组
数组的声明方法基本上与此前所看到的变量声明的方法相同,唯一区别是应该在紧跟数组名的方括号内指出数组元素的数量。例如,我们可以用下面这条声明语句,声明图4-1中的整数数组height:
- long height[6];
因为每个long数值在内存中要占用4个字节,所以整个数组共需24个字节。数组长度只受运行该程序的计算机上内存总量的限制。
数组可以被声明成任意类型。例如,我们可以用下面这条语句,声明两个用来存储一组发动机的体积和功率的数组:
- double cubic_inches[10]; // Engine size
- double horsepower[10]; // Engine power output
这两个数组可存储10台发动机的体积和功率,其索引值为0~9。正如前面在其他变量的声明语句中所看到的那样,我们可以用一条语句声明多个同类型的数组,但实践中在分开的语句中声明变量往往更合适。
试一试:使用数组
为练习如何使用数组,假设我们需要记录每次给汽车购买的汽油量和相应的里程表读数。我们可以编写程序来分析这些数据,以了解不同时间段的汽油消耗情况。
- // Ex4_01.cpp
- // Calculating gas mileage
- #include <iostream>
- #include <iomanip>
-
- using std::cin;
- using std::cout;
- using std::endl;
- using std::setw;
-
- int main()
- {
- const int MAX = 20; // Maximum number of values
- double gas[ MAX ]; // Gas quantity in gallons
- long miles[ MAX ]; // Odometer readings
- int count = 0; // Loop counter
- char indicator = 'y'; // Input indicator
-
- while( (indicator == 'y' || indicator == 'Y') && count < MAX )
- {
- cout << endl
- << "Enter gas quantity: ";
- cin >> gas[count]; // Read gas quantity
- cout << "Enter odometer reading: ";
- cin >> miles[count]; // Read odometer value
-
- ++count;
- cout << "Do you want to enter another(y or n) ";
- cin >> indicator;
- }
-
- if(count <= 1) // count = 1 after 1 entry completed
- { // ... we need at least 2
- cout << endl
- << "Sorry - at least two readings are necessary.";
- return 0;
- }
-
- // Output results from 2nd entry to last entry
- for(int i = 1; i < count; i++)
- cout << endl
- << setw(2) << i << "." // Output sequence number
- << "Gas purchased = " << gas[i] << " gallons" // Output gas
- << " resulted in " // Output miles per gallon
- << (miles[i] - miles[i - 1])/gas[i] << " miles per gallon.";
- cout << endl;
- return 0;
- }
程序假设每次都给油箱加满汽油,因此购买的汽油量就是行驶的里程所需的汽油消耗量。下面是本程序产生的输出:
- Enter gas quantity: 12.8
- Enter odometer reading: 25832
- Do you want to enter another(y or n) y
- Enter gas quantity: 14.9
- Enter odometer reading: 26337
- Do you want to enter another(y or n) y
-
- Enter gas quantity: 11.8
- Enter odometer reading: 26598
- Do you want to enter another(y or n) n
-
- 1.Gas purchased = 14.9 gallons resulted in 33.8926 miles per gallon.
- 2.Gas purchased = 11.8 gallons resulted in 22.1186 miles per gallon.
示例说明
因为必须得到两次里程表读数的差值,才能计算用掉的汽油所能行驶的里程,所以我们只使用第一对输入值的里程表读数,而忽略第一次购买的汽油量,这些汽油是在以前行驶的路程中消耗掉的。
在输出中显示的第二段时间内,交通状况必定相当糟糕,或者是经常踩刹车。
用来存储输入数据的两个数组gas和miles的大小取决于常量MAX。通过改变MAX的值,我们即可使该程序适应最大数量不同的输入值集合。这种技术经常用来使程序灵活地适应要处理的信息量。当然,编写程序代码时必须考虑到const变量指定的数组大小或任何其他参数。不过,上述要求增加的难度不算大,因此没有任何理由不采用这种技术。我们稍后还将学习如何在程序执行时动态分配内存,从而不必再预先给数据分配固定数量的内存。
输入数据
while循环读取数据值。因为循环变量的范围是从0到MAX-1,所以该程序不允许其用户输入超过数组容量的数据量。程序分别将变量count和indicator初始化为0和y,因此while循环至少执行一次。程序提示用户输入要求的各个数值,然后将输入值读入适当的数组元素中。用来存储具体数值的元素由变量count确定,第一次输入时该变量是0。我们以count作为索引值,在cin语句中指定数组元素,然后使count加1,从而为下次输入做好准备。
输入各个数值之后,程序提示用户确认是否要输入另外的数值。输入的字符被读入indicator变量中,然后在循环条件中进行测试。如果没有输入y或Y,则循环终止,变量count小于指定的最大值MAX。
输入循环结束以后(无论通过什么方法),count的值将比每个数组中最后输入的元素的索引值大1(记住,我们每次输入新元素之后都使该变量加1)。检查该变量可以验证是否至少输入了两对数值。如果不是,则程序将以一条适当的消息结束,因为计算里程至少需要两个里程表读数。
生成结果
输出是在for循环中产生的。控制变量i从1变化到count-1,使程序计算当前元素miles[i]和前一个元素miles[i-1]之间的差值,以作为本次行驶的里程。注意,数组的索引值可以是任何结果为整数的表达式,前提是该整数是相应数组的合法索引值-- 即从0到数组元素的数量减1。
如果索引表达式的值不在对应于合法数组元素的范围之内,那么程序将引用一个错误的存储单元,其中可能包含其他数据、无用信息甚至程序代码。如果对错误元素的引用出现在表达式中,则程序将使用随机的一个数据值进行计算,这当然会产生意外结果。如果需要将某种结果存储在数组元素中,但使用的是非法索引值,则将覆盖位于该存储单元的任何数据。如果被破坏的数据是程序代码的组成部分,则结果是灾难性的。当我们使用非法索引值时,编译或运行过程中并没有任何警告产生。唯一能够避免此类错误的方法是用程序代码来防止其发生。
cout语句为除第一对以外的所有输入值生成输出。程序还使用循环控制变量i,为每行输出生成一个行号。每加仑汽油行驶的英里数是在输出语句中直接计算的。在表达式中使用数组元素的方式与使用任何其他变量完全相同。