当前位置: 首页 > 文档资料 > C++大学教程 >

4.9 多下标数组

优质
小牛编辑
129浏览
2023-12-01

C++ 中有多下标数组。多下标数组常用于表示由行和列组成的表格。要表示表格中的元素,就要指定两个下标:习惯上第一个表示元素的行,第二个表示元素的列。
用两个下标表示特定的表格或数组称为双下标数组(double-subscripted array)。注意,多下标数组可以有多于两个的下标,C++编译器支持至少12个数组下标。图4.21演示了双下标数组a。数组包含三行四列,因此是3 x 4数组。一般来说,m行和n列的数组称为 m x n 数组。

数组a中的每个元素如图4.21所示,元素名字表示为 a[i][j] ,i 和 j 是数组名,i和j是惟一标识a中每个元素的下标。注意第一行元素名的第一个下标均为0,第四列的元素名的第二个下标均为3。

常见编程错误 4.11

把双下标数组元素 a[x][y] 误写成 a[x,Y] 。实际上, a[x,y] 等于 a[y] ,因为 C++ 将包含返号运算符的表达式 (x,y) 求值为 y(逗号分隔的表达式中最后一个项目)。

多下标数组可以在声明中初始化,就像单下标数组一样。例如,双下标数组 b[2][2] 可以声明和初始化如下:

int b[2][2] = { { l, 2 }, { 3,4 } };

数值用花括号按行分组,因此1和2初始化b[0][0]和b[0][1],3和4初始化b[1][0]和b[1][1]。

如果指定行没有足够的初始化值,则该行的其余元素初始化为0。这样,下列声明:

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

初始化 b[0][0] 为 1、b[0][1] 为 0、b[1][0)] 为 3、b[1][1] 为 4。

图4.22演示了声明中初始化双下标数组。程序声明三个数组,各有两行三列。array1的声明在两个子列表中提供六个初始化值。第一个子列表初始化数组第一行为1、2、3,第二个子列表初始化数组第二行为4、5、6。如果从array1初始化值列表中删除每个子列表的花括号,则编译器自动先初始化第一行元素,然后初始化第二行元素。
array2 声明提供六个初始化值。初始化值先赋给第一行,再赋给第二行。任何没有显式初始化值的元素都自动初始化为0,因此 array2[1][2] 自动初始化为 0。

1 // Fig. 4.22: fig04_22.cpp
2 // Initializing multidimensional arrays
3 #include <iostream.h>
4
5 void printArray( int [][ 3 ] );
6
7 int main()
8 {
9 int arrayl[ 2 ][ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 } },
10 array2[ 2][ 3] { 1, 2, 3, 4, 5 },
11 array3[ 2][ 3] ={ { 1, 2 }, { 4 } };
12
13 cout << "Values in arrayl by row are:" << endl;
14 printArray( array1 );
15
16 cout << "Values in array2 by row are:" << endl;
17 printArray( array2);
18
19 cout << "Values in array3 by row are:" << endl;
20 printArray( array3 );
21
22 return 0;
23 }
24
25 void printArray( int a[][ 3 ] )
26 {
27 for (int i = 0; i < 2; i++ ) {
28
29 for ( int j = 0; j < 3; j++ )
30 cout << a[ i ][ j ] << ' ';
31
32 cout << endl;
33 }
34 }

输出结果:

Values in array1 by row are:
1 2 3
4 5 6
Values in array2 by row are:
1 2 3
4 5 0
Values in array3 by row are:
1 2 0
4 0 0

图4.22 初始化多维数组

array3 的声明在两个子列表中提供3个初始化。第一行的子列表显式地将第一行的前两个元素初始化为1和2,第3个元素自动初始化为0。第二行的子列表显式地将第一个元素初始化为4,最后两个元素自动初始化为0。

程序调用函数printArray输出每个数组的元素。注意函数定义指定数组参数为int a[][3]。函数参数中收到单下标数组时,函数参数表中的数组括号是空的。多下标数组第一个下标的长度也不需要,但随后的所有下标长度都是必须的。编译器用这些长度确定多下标数组中元素在内存中的地址。不管下标数是多少,所有数组元素都是在内存中顺序存放。在双下标数组中,第一行后面的内存地址存放第二行。

在参数声明中提供下标使编译器能告诉函数如何找到数组中的元素。在双下标数组中,每行是一个单下标数组。要找到特定行中的元素,函数要知道每一行有多少元素,以便在访问数组时跳过适当数量的内存地址。这样,访问a[1][2]时,函数知道跳过内存中第一行的3个元素以访问第二行(行1),然后访问这一行的第3个元素(元素2)。
许多常见数组操作用for重复结构。例如,下列for结构(见图4.21)将数组a第三行的所有元素设置为o:

for(column=0; coulumn<4; column++)
a[2][Column] = 0;

我们指定第三行,因此知道第一个下标总是2 (0是第一行的下标,1是第二行的下标)。for循环只改变第二个下标(即列下标)。上述for结构等同于下列赋值语句:

a[2][0]=0;
a[2][1]=0;
a[2][2]=0;
a[2][3]=0;

下列嵌套for结构确定数组a中所有元素的总和:

total = 0;
for ( row = O; row < 3; row++ )
for ( column = 0; column < 4; column++ )
total += a [ row ] [ column ] ;

for结构一次一行地求数组中所有元素的和。外层for结构首先设置row(即行下标)为0,使第一行的元素可以用内层for结构求和。然后外层for结构将row递增为1,使第二行的元素可以用内层for结构求和。然后外层for结构将mw递增为2,使第三行的元素可以用内层for结构求和。结束嵌套br结构之后,打印结果。

图4.23 的程序对 3 x 4 数组 studentCrades 进行几个其他常见数组操作。每行数组表示一个学生,每列表示学生期末考试中4门成绩中的一门成绩。数组操作用4个函数进行。函数 mimimum 确定该学期所有学生考试成绩中的最低成绩。函数maximum确定该学期所有学生考试成绩中的最高成绩。

函数 average 确定每个学生该学期的平均成绩。函数 printArray 以整齐的表格形式输出双下标数组。

1 // Fig. 4.23: fig04_23.cpp
2 // Double-subscripted array example
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 const iht students = 3; // number of students
7 const iht exams = 4; // number of exams
8
9 int minimum( int [][ exams ], int, int );
10 int maximum(int [][ exams ], int, int };
11 float average( int [], int );
12 void printArray( int [][ exams ], int, int );
13
14 int main()
I5 {
16 int studentGrades[ students ][ exams ] =
17 { { 77, 68, 86, 73 },
18 { 96, 87, 89, 78 },
19 { 70, 90, 86, 81 } };
20
21 cout << "The array is:\n";
22 printArray( studentGrades, students, exams );
23 cout << "\n\nLowest grade: "
24 << minimum( studentGrades, students, exams )
25 << "\nHighest grade:"
26 << maximum( studentGrades, students, exams ) << '\n';
27
28 for ( int person = 0; person < students; person++ }
29 cout << "The average grade for student" << person << "is"
3O
31 << setprecision( 2 )
32 << average( studentGrades[ person ], exams ) << endl;
33
34 return 0;
35
36
37 // Find the minimum grade
38 int minimum( int grades[][ exams ], int pupils, int tests )
39 {
40 int lowGrade = 100;
41
42 for ( int i = O; i < pupils; i++ )
44 for ( int j = 0; j < tests; j++ )
45
46 if ( grades[ i ][ j ] < lowGrade )
47 lowGrade = grades[ i ] [ j ];
48
49 return lowGrade;
5O }
51
52 // Find the maximum grade
53 int maximum( int grades[][ exams ], iht pupils, iht tests )
54 {
55 int highgrade = 0;
56
57 for ( int i = 0; i < pupils; i++ )
58
59 for (int j = 0; j < tests; j++ )
60
61 if ( grades[ i ][ j ] > highgrade )
62 highgrade = grades[ i ][ j ];
63
64 return highgrade;
65 }
66
67 // Determine the average grade for a particular student
68 float average(int setofGrades[],int tests)
69 {
70 int total = 0;
71
72 for ( int i = 0; i < tests; i++ )
73 total += setofGrades[ i ];
74
75 return ( float ) total / tests;
76 }
77
78 // Print the array
8O {
8I cout <<" [ 0 ] [ 1 ] [ 2 ] [ 3 ]";
83 for (int i = 0; i < pupils; i++ ) {
84 cout << "\nstudentGrades[ "<< i << "] ";
85
86 for(int j=0; j<tests;j++)
87 cout << setiosflags( ios::left ) << setw( 5 )
88 << grades[ i ][ j ];
89 }
90
输出结果:
The array is:
[0] [1] [2] [3]
StudentGrades[ 0 ] 77 68 86 73
StudentGrades[ 1 ] 96 87 98 78
StudentGrades[ 2 ] 70 90 86 81
Lowest grade: 68
Highest grade: 96
The average grade for student 0 is 76.00
The average grade for student 1 is 87.50
The average grade for student 2 is 81.75

图 4.23 使用双下标数组举例

函数 minimum、maximum 和 printArray 取得三个参数——studentGrades 数组(在每个函数中调用 grades)、学生数(数组行)、考试门数(数组列)。每个函数用嵌套for结构对grades数组循环。

下列嵌套 for 结构来自函数 mlmmum 的定义:

for(i = 0;i<pupils;i++)
for(j = O;j<tests;j++)
if(grades[i][j] < lowGrade)
lowGrade = grades[i][i];

外层for结构首先将i(行下标)设置为 0,使第一行的元素可以和内层for结构体中的变量 lowGrade 比较。内层 for 结构比较lowGrade与4个成绩中的每一门成绩。如果成绩小于lowGrade,则 lowGrade 设置为该门成绩。然后外层for结构将行下标加到1,第二行的元素与变量 lowGrade 比较。接着外层for结行下标加到2,第三行的元素与变量 lowGrade 比较。嵌套for结构执行完成后,lowGrade 包含双下标数组中的最小值。函数 maximum 的执行过程与函数 minimum 相似。

函数 average 取两个参数:一个单下标数组为某个学生的考试成绩,一个数字表示数组中有几个考试成绩。调用average时,第一个参数 studentGrades[student] 指定将双下标数组 studentGrades 的特定行传递给 average。例如,参数 studentGrad[1] 表示双下标数组 studentGrades 第二行中存放的4个值(成绩的单下标数组)。双下标数组可以看作元素是单下标数组的数组。函数 average 计算数组元素的和,将总和除以考试成绩的个数,并返回一个浮点数结果。