📄 04章 数组.txt
字号:
67 cout << endl;
68 }
69
70 // Print one row of output showing the current
71 // part of the array being processed.
72 void printRow( int b[ ], int low, int mid, int high, int size )
73 {
74 for ( int i = 0; i < size; i++ )
75 if ( i < low || i > high )
76 cout << " ";
77 else if ( i == mid ) // mark middle value
78 cout << setw( 3 ) << b[ i ] << '*';
79 else
80 cout << setw( 3 ) << b[ i ] << ' ';
81
82 cout << endl;
83 }
输出结果:
Enter a number between 0 and 28:25
Subscripts:
O 1 2 3 4 5 6 7 8 9 10 11 12 13 14
------------------------------------------------------------------------------
O 2 4 6 8 10 12 14* 16 18 20 22 24 26 29
16 18 20 22* 24 26 28
24 26* 28
24*
25 not found
Enter a number between 0 and 28: 8
Subscripts:
O 1 2 3 4 5 6 7 8 9 lO ll 12 13 14
------------------------------------------------------------------------------
O 2 4 6 8 lO 12 14* 16 18 20 22 24 26 28
O 2 4 6* 8 10 12
8 lO* 12
8*
8 found in array element 4
Enter a number between O and 28: 6
Subscrlpts:
O l 2 3 4 5 6 7 8 9 10 11 12 13 14
------------------------------------------------------------------------------
O 2 4 6 8 10 12 14* 16 18 20 22 24 26 28
O 2 4 6* 8 10 12
6 found ln array element 3
图4.20排序数组的折半查找过程
4.9 多下标数组
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(逗号分隔的表达式中最后一个项目)。
图4.21 三行四列的双下标数组
多下标数组可以在声明中初始化,就像单下标数组一样。例如,双下标数组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 O 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=O;coulumn<4;column++)
a[2][Column] = O;
我们指定第三行,因此知道第一个下标总是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计算数组元素的和,将总和除以考试成绩的个数,并返回一个浮点数结果。
4.10 有关对象的思考:确定类的行为
第2章和第3章“有关对象的思考”一节完成了电梯模拟程序面向对象设计的前两步,即确定实现电梯模拟程序的类和这些类的属性。
本节要确定实现电梯模拟程序所需的类行为。第5章将介绍这些类对象之间的交互。
下面要考虑一些实际类对象的行为。收音机的行为包括可以选台和设置音量。汽车的行为包括加速(按油门板)和减速(按制动闸)。
可以看出,对象通常不是自动做出行为,而是在向对象发出消息(message)时调用特定行为,这个消息表示对象要做出特定行为。这很像函数调用,C++中就是这样向对象发出消息的。
电梯实验宣任务3
1.继续处理第3章生成的事实文件。其中将文件分成两组事实,第一组是属性,第二组是其他事实。
2.对每个数,加进第三个组,称为“行为”。用该组存放类的每个行为,对象调用这些行为来做某件事(即通过向对象发出消息)。例如,人可以单击按钮,因此将pushButton列为按钮类的行为。函数pnshButton和按钮类的其他行为称为成员函数(member function)或方法(method)。类的属性(如按钮“开”或“关”)通常称为按钮类的数据成员(data member)。
类的成员函数通常操作类的数据成员(如pushBuuon改变按钮的属性为“开”)。成员函数通常还向其他类的对象发送消息(例如按钮对象向电梯发送comeGetMe消息)。假设某人按按钮时电梯的按钮亮
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -