📄 04章 数组.txt
字号:
C++大学教程(第4章 数组-01)
教学目标
●介绍数组数据结构
●介绍用数组存放、排序与查找数值清单与表格
●介绍如何声明数组、初始化数组和引用数组的各个元素
●将数组传递到函数中
●介绍基本排序方法
●声明和操作多下标数组
4.1 简介
本章是介绍数据结构的重要课题。数组(array)数据结构由相同类型的相关数据项组成。第6章介绍结构(structure)和类(class),两者都可以带有不同类型的相关数据项。数组和结构是静态项目.在整个程序执行期间保持相同长度(当然,也可以用自动存储类,在每次进入和离开定义的块时生成和删除)。第15章介绍链表、队列、堆栈、树之类的动态数据结构如何在程序执行期间改变长度。本章介绍的数组是C语言中的指针数组(第5章将介绍指针)。第8章“运算符重载”和本书末尾的"标准模板库(STL)"一章将介绍用面向对象编程技术将数组实现为完全成熟的对象,这些基于对象的数组比第4章介绍的类C语言的指针数组更安全、更灵活。
4.2 数组
数组是具有相同名称和相同类型的一组连续内存地址。要引用数组中的特定位置或元素,就要指定数组中的特定位置或元素的位置号(position number)。
图4.1显示了整型数组c。这个数组包含12个元素。可以用数组名加上方括号(1))中该元素的位置号引用该元素。数组中的第一个元素称为第0个元素(zeroth elemem)。这样,c数组中的第一个元素为c[0],c数组中的第二个元素为c[1],c数组中的第七个元素为c[6],一般来说,c数组中的第i个元素为c[i-1]。数组名的规则与其他变量名相同。
方括号中的位置号通常称为下标(subscript),下标应为整数或整型表达式。如果程序用整型表达式下标,则要求值这个整型表达式以确定下标,例如,假设a等于5,b等于6,则下列语句:
c[a + b] += 2
将数组元素c[11]加2。注意带下标的数组名是个左值,可用于赋值语句的左边。
图4.1中整个数组的名称为c,该数组的12个元素为c[0]、c[1]、c[2]...c[11]。的值为-45、c[1]的值为6、c[2]的值为0,c[7]的值为62、c[11]的值为78。要打印数组c中前三个元素的和,用下列语句:
cout<< c[0]+c[1]+c[2] <<endl;
要将数组c的第7个元素的值除以2,并将结果赋给变量x,用下列语句:
x = c[6] / 2;
常见编程错误 4.1
一定要注意“数组的第7个元素”与“数组元素7”之间的差别。由于数组下标从0开始,因此“数组第7个元素”的下标为6,而“数组元素7”的下标为7,是第8个元素。这常常是“差1错误”的原因。
包括数组下标的方括号实际上是个C++运算符。方括号的优先级与括号相同。图4.2显示了本书前面介绍的C++运算符优先级和结合律。运算符优先级从上到下逐渐减少。
运算符 结合律 类型
() [] 从左向右 括号
++ -- + - ! static_cast<type>() 从右向左 一元
* / % 从左向右 乘
+ - 从左向右 加
<< >> 从左向右 插入/读取
< <= > >= 从左向右 关系
== != 从左向右 相等
&& 从左向右 逻辑与
|| 从左向右 逻辑或
?: 从右向左 条件
= += -= *= /= %= 从左向右 赋值
, 从左向右 逗号
图 4.2 运算符的优先级和结合律
4.3 声明数组
数组要占用内存空间。程序员指定每个元素的类型和每个数组所要的元素,使编译器可以保留相应的内存空间。要告诉编译器对整型数组c保留12个元素,可以声明如下:
int c[12];
可以在一个声明中为几个数组保留内存。下列声明对整型数组b保留100个元素,对整型数组x保留27个元素:
int b[100],x[27];
数组可以声明包含其他数据类型。例如,char类型的数组可以存放字符串。字符串及其与字符数组的相似性(C++从c语言继承的关系)和指针与数组的关系将在第5章介绍。在介绍面向对象编程后,我们将讨论成熟的字符串对象。
4.4 使用数组的举例
图4.3的程序用for重复结构将10个元家的整型数组n的元素初始化为0,并用表格形式打印数组。第一个输出语句显示for结构中所打印列的列标题。记住,setw指定下一个值的输出域宽。
可以在数组声明中用等号和逗号分隔的列表(放在花括号中)将数组中的元素初始化。程序4.4将七个元素的整型数组初始化并用表格形式打印数组。
1 // Fig. 4.3: fig04_03.cpp
2 // initializing an array
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7 {
8 int i, n[10];
9
10 for ( i = 0; i < 10; i++ ) // initialize array
11 n[ i ] = 0;
12
13 cout << "Element" << setw( 13 ) << "Value" << endl;
14
15 for(i=0;i<10;i++) // print array
16 cout << setw( 7 ) << i << setw( 13 ) << n[ i ] << endl;
17
18 return O;
19 }
输出结果:
Element value
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
图4.3 将10个元素的整型数组n的元素初始化为0
1 // Fig. 4.4:fig04 04.cpp
2 // Initializing an array with a declaration
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7 {
8 int n[ 10 ] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 };
9
10 cout << "Element" << setw( 13 ) << "Value" << endl;
11
12 for ( int i = 0; i < 10; i++ )
13 cout << setw( 7 ) << i << setw( 13 ) << n[ i ] << endl;
14
15 return 0;
16 }
输出结果:
Element Value
0 32
1 27
2 64
3 18
4 95
5 14
6 9O
7 7O
8 6O
9 37
图4.4 用声明将数组中的元素初始化
如果初始化的元素比数组中的元素少,则其余元素自动初始化为0。例如,可以用下列声明将图4.3中数组n的元素初始化为0:
int n[1O] = {O};
其显式地将第一个元素初始化为0,隐式地将其余元素自动初始化为0,因为初始化值比数组中的元素少。程序员至少要显式地将第一个元素初始化为0,才能将其余元素自动初始化为0。图4.3的方法可以在程序执行时重复进行。
常见编程错误4.2
需要初始化数组元素而没有初始化数组元素是个逻辑错误。
下列数组声明是个逻辑错误:
int n[5] = { 32,27, 64, 18, 95, 14};
因为有6个初始化值,而数组只有5个元素。
常见编程错误4.3
初始化值超过数组元素个数是个逻辑错误。
如果带初始化值列表的声明中省略数组长度,则数组中的元素个数就是初始化值列表中的元素个数。例如:
int n[] = { 1, 2, 3, 4, 5};
生成五个元素的数组。
性能提示4.1
如果不用执行时的赋值语句初始化数组而用数组初始化值列表在编译时初始化数组,则程序执行速度更快。
图4.5的程序将10个元素的数组s初始化为整数2、4、6、…20,并以表格形式打印数组。这些数值是将循环计数器的值乘以2再加上2产生的。
1 // Fig. 4.5: figO405.cpp
2 // Initialize array s to the even integers from 2 to 20.
3 #include <iostream.h>
4 #include <iomanip.h>
5
6 int main()
7
8 const int arraySize = 10;
9 int j, s[arraySize];
10
11 for ( j = 0; j < arraySize; j++ ) // set the values
12 si [j] = 2 + 2* j;
13
14 cout << "Element" << setw( 13 ) << "Value" << endl;
15
16 for ( j - 0; j < arraysize; j++ ) // print the values
17 cout << setw( 7 ) << j << setw( 13 ) << s[ j ] << endl;
18
19 return 0;
20 }
输出结果:
Element Value
0 2
1 4
2 6
3 8
4 10
5 12
6 14
7 16
8 18
9 20
图4.5 将产生的值赋给数组元素
下列语句:
const int arraySlze:1O
用const限定符声明常量变量arrayySize的值为10。常量变量应在声明时初始化为常量表达式,此后不能改变(图4.6和图4.7)。常量变量也称为命名常量(named constant)或只读变量(read-only variable)。
注意,常量变量一词是自相矛盾的,称为逆喻(像“龙虾”之类的名词)。
1 // Fig. 4.6: fig04_06.cpp
2 // Using a properly initialized constant variable
3 #include <iostream.h>
4
5 int main()
6 {
7 const int x - 7; // initialized constant variable
8
9 cout << "The value of constant variable x is:"
10 << x << endl;
11
12 return 0;
13 }
输出结果:
The value of constant variable x is: 7
图4.6 正确地初始化和使用常量变量
1 // Fig. 4.7:fig04 07.cpp
2 // A const object must be initialized
3
4 int main()
5 {
6 const int x; // Error: x must be initialized
7
8 x = 7; // Error: cannot modify a const variable
9
10 return 0;
11}
输出结果:
Compiling FIG04-7.CPP:
Error FIG04_7.CPP 6:Constant variable,x’must be initialized
Error FIG04_7.CPP 8:Cannot modify a const object
图4.7const 对象应初始化
常见编程错误4.4
在执行语句中对常量变量赋值是个语法错误。
常量变量可以放在任何出现常量表达式的地方。图4.5中,用常量变量arraySize指定数组s的长度:
int j,s[arraySize];
幸常见编程错误4.5
只能用常量声明自动和静态数蛆,否则是个语法错误。
用常量变量声明数组长度使程序的伸缩性更强。图4.5中,要让第一个for循环填上1000个数组元素,只要将anaySize的值从10变为1000即可。如果不用常量变量arraySize,则要在程序中进行三处改变才能处理1000个数组元素。随着程序加大,这个方法在编写清晰的程序中越来越有用。
软件工程视点4.1
将每个数组的长度定义为常量变量而不是常量,能使程序的伸缩性更强。
编程技巧4.1
将每个数组的长度定义为常量变量而不是常量,能使程序更清晰。这个方法可以取消“魔数”,例如,在处理10元素数组的程序中重复出现长度10使数字10人为地变得重要,程序中存在的与数组长度无关的其他数字10时可能使读者搞乱。
图4,8中的程序求12个元素的整型数组a中的元素和,for循环体中的语句进行求和。请注意,数组a的初始化值通常是用户从键盘输入的。例如,下列for结构:
for ( int j=0; j < arraySize;j++ )
cin>>a[j];
一次一个地从键盘读取数值,并将数值存放在元素a[j]中。
下一个例子用数组汇总调查中收集的数据。考虑下列问题:
40个学生用1到10的分数评价学生咖啡屋中的食品质量(1表示很差,10表示很好)。将40个值放在整型数组中,并汇总调查结果。
这是典型的数组应用(如图4.9)。我们要汇总每种回答(1到10)的个数。数组responses是40个元素的评分数组。我们用11个元素的数组frequency计算每个答案的个数,忽略第一个元素frequeney[0],因为用1分对应frequency[1]而不是对应frequency[0]更好理解。这样可以直接用回答的分数作为frequency数组的下标。
1 // Fig. 4.8:fig04 OS.cppf
2 // Compute the sum of the elements of the array
3 #include <iostream.h>
4
5 int main()
6 {
7 const iht arraySize = 12;
8 int a[ arraySize ] = { 1, 3, 5, 4, 7, 2, 99,
9 16, 45, 67, 89, 45 };
10 int total = 0;
11
12 for (int i = 0; i < arraySize ; i++ )
13 total += a[ i ];
14
15 cout << "Total of array element values is "<< total << endl;
16 return 0;
17 }
输出结果:
Total of array element values is 383
图4.8计算数组元素和
1 // Fig. 4.9: fig04_09.cpp
2 // Student poll program
3 8include <iostream.h>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -