1、第5章 数组,5.1 数组的概念 5.2 一维数组的定义和引用 5.3 二维数组的定义和引用 5.4 用数组名作函数参数 5.5 字符数组 *5.6 C+处理字符串的方法字符串类与字符串变量,概括地说: 数组是有序数据的集合。要寻找一个数组中的某一个元素必须给出两个要素,即数组名和下标。数组名和下标惟一地标识一个数组中的一个元素。 数组是有类型属性的。同一数组中的每一个元素都必须属于同一数据类型。一个数组在内存中占一片连续的存储单元。如果有一个整型数组a,假设数组的起始地址为2000,则该数组在内存中的存储情况如图5.1所示。,5.1 数组的概念,图5.1,引入数组就不需要在程序中定义大量的变
2、量,大大减少程序中变量的数量,使程序精炼,而且数组含义清楚,使用方便,明确地反映了数据间的联系。许多好的算法都与数组有关。熟练地利用数组,可以大大地提高编程和解题的效率,加强了程序的可读性。 C+用方括号来表示下标,如用s1,s2,s3 分别代表s1,s2,s3。,定义一维数组的一般格式为 类型标识符 数组名常量表达式; 例如 int a10; 它表示数组名为a,此数组为整型,有10个元素。 说明: (1) 数组名定名规则和变量名相同,遵循标识符定名规则。,5.2 一维数组的定义和引用 5.2.1 定义一维数组,(2) 用方括号括起来的常量表达式表示下标值,如下面的写法是合法的: int a1
3、0; int a2*5; int an*2; /假设前面已定义了n为常变量 (3) 常量表达式的值表示元素的个数,即数组长度。例如,在“int a10;”中,10表示a数组有10个元素,下标从0开始,这10个元素是: a0,a1,a2,a3,a4,a5,a6,a7, a8,a9。注意最后一个元素是a9而不是a10。,(4) 常量表达式中可以包括常量、常变量和符号常量,但不能包含变量。也就是说,C+不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。例如,下面这样定义数组是不行的: int n; cinn; /输入a数组的长度 int an; /企图根据n的值决定数组的长度
4、 如果把第1,2行改为下面一行就合法了: const int n=5;,数组必须先定义,然后使用。只能逐个引用数组元素的值而不能一次引用整个数组中的全部元素的值。 数组元素的表示形式为 数组名下标 下标可以是整型常量或整型表达式。例如 a0= a5+ a7- a2*3,5.2.2 引用一维数组的元素,例5.1 数组元素的引用。 #include using namespace std; int main( ) int i,a10;for (i=0;i=0;i-) coutai ;coutendl;return 0; 运行结果如下: 9 8 7 6 5 4 3 2 1 0 程序使a0a9的值为0
5、9,然后按逆序输出。,(1) 在定义数组时分别对数组元素赋予初值。例如 int a10=0,1,2,3,4,5,6,7,8,9; (2) 可以只给一部分元素赋值。例如 int a10=0,1,2,3,4; (3) 如果想使一个数组中全部元素值为1,可以写成 int a10=1,1,1,1,1,1,1,1,1,1; 不能写成 int a10=1*10; 不能给数组整体赋初值。 (4) 在对全部数组元素赋初值时,可以不指定数组长度。例如 int a5=1,2,3,4,5; 可以写成 int a=1,2,3,4,5;,5.2.3 一维数组的初始化,例5.2 用数组来处理求Fibonacci数列问题。
6、 可以用20个元素代表数列中的20个数,从第3个数开始,可以直接用表达式fi=fi-2+fi-1求出各数。 程序如下: #include #include using namespace std; int main( ) int i;int f20=1,1; /f0=1,f1=1for(i=2;i20;i+),5.2.4 一维数组程序举例,fi=fi-2+fi-1; /在i的值为2时,f2=f0+f1,依此类推for(i=0;i20;i+) /此循环的作用是输出20个数if(i%5=0) coutendl; /控制换行,每行输出5个数据 coutsetw(8)fi; /每个数据输出时占8列宽度
7、 coutendl; /最后执行一次换行 return 0; 运行结果如下: (空一行)1 1 2 3 58 13 21 34 5589 144 233 377 610 987 1597 2584 4181 6765,例5.3 编写程序,用起泡法对10个数排序(按由小到大顺序)。 起泡法的思路是:将相邻两个数比较,将小的调到前头。见图5.2。 然后进行第2趟比较,对余下的前面5个数按上法进行比较,见图5.3。图5.2 图5.3,可以推知,如果有n个数,则要进行n-1趟比较(和交换)。在第1趟中要进行n-1次两两比较,在第j趟中要进行n-j次两两比较。 根据以上思路写出程序,今设n=10,本例定
8、义数组长度为11,a0不用,只用a1a10,以符合人们的习惯。从前面的叙述可知,应该进行9趟比较和交换。 #include using namespace std; int main( ) int a11;int i,j,t;coutinput 10 numbers :endl;for (i=1;i11;i+) /输入a1a10,cinai;coutai+1) /如果前面的数大于后面的数t=ai;ai=ai+1;ai+1=t; /交换两个数的位置,使小数上浮coutthe sorted numbers :endl;for(i=1;i11;i+) /输出10个数coutai ;coutendl;
9、return 0; 运行情况如下: input 10 numbers: 3 5 9 11 33 6 -9 -76 100 123 the sorted numbers: -76 -9 3 5 6 9 11 33 100 123,具有两个下标的数组称为二维数组。有些数据要依赖于两个因素才能惟一地确定,例如有3个学生,每个学生有4门课的成绩,显然,成绩数据是一个二维表,如书中表5.1所示。 想表示第3个学生第4门课的成绩,就需要指出学生的序号和课程的序号两个因素,在数学上以S3,4表示。在C+中以s34表示,它代表数据73。,5.3 二维数组的定义和引用,定义二维数组的一般形式为 类型标识符 数组
10、名常量表达式常量表达式 例如 float a34,b510; 定义a为34(3行4列)的单精度数组,b为510(5行10列)的单精度数组。注意不能写成“float a3,4,b5,10;”。C+对二维数组采用这样的定义方式,使我们可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。例如,可以把a看作是一个一维数组,它有3个元素:a0,a1,a2,每个元素又是一个包含4个元素的一维数组,见图5.4。a0,a1,a2是3个一维数组的名字。,5.3.1 定义二维数组,图5.4 上面定义的二维数组可以理解为定义了3个一维数组,即相当于 float a04,a14,a24 此处把a0,a1
11、,a2作一维数组名。C+的这种处理方法在数组初始化和用指针表示时显得很方便,这在以后会体会到。,C+中,二维数组中元素排列的顺序是:按行存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素。图5.5表示对a34数组存放的顺序。图5.5 C+允许使用多维数组。有了二维数组的基础,再掌握多维数组是不困难的。例如,定义三维数组的方法是,float a234; 定义float型三维数组a,它有234=24个元素。多维数组元素在内存中的排列顺序:第一维的下标变化最慢,最右边的下标变化最快。例如,上述三维数组的元素排列顺序为 a000a001a002a003a010a011a012a013a020a
12、021a022a023a100a101a102a103a110a111a112a113a120a121a122a123,二维数组的元素的表示形式为 数组名 下标下标 如a23。下标可以是整型表达式,如a2-12*2-1。不要写成a2,3,a2-1,2*2-1形式。 数组元素是左值,可以出现在表达式中,也可以被赋值,例如 b12=a23/2; 在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。常出现的错误是,5.3.2 二维数组的引用,int a34; /定义3行4列的数组 a34=15; /引用a34元素 定义a为34的数组,它可用的行下标值最大为2,列坐标值最大为3。最多可以用到
13、a23,a34就超过了数组的范围。 请严格区分在定义数组时用的a34和引用元素时的a34的区别。前者a34用来定义数组的维数和各维的大小,后者a34中的3和4是下标值,a34代表某一个元素。,可以用下面的方法对二维数组初始化: (1) 分行给二维数组赋初值。如 int a34=1,2,3,4,5,6,7,8,9,10,11,12; 这种赋初值方法比较直观,把第1个花括号内的数据赋给第1行的元素,第2个花括号内的数据赋给第2行的元素即按行赋初值。 (2) 可以将所有数据写在一个花括号内,按数组排列的顺序对各元素赋初值。如 int a34=1,2,3,4,5,6,7,8,9,10,11,12; 效
14、果与前相同。但以第1种方法为好,一行对一行,界限清楚。用第2种方法如果数据多,写成一大片,容易遗漏,也不易检查。,5.3.3 二维数组的初始化,(3) 可以对部分元素赋初值。如 int a34=1,5,9; 它的作用是只对各行第1列的元素赋初值,其余元素值自动置为0。赋初值后数组各元素为 1 0 0 0 5 0 0 0 9 0 0 0 也可以对各行中的某一元素赋初值: int a34=1,0,6,0,0,11; 初始化后的数组元素如下: 1 0 0 0 0 6 0 0 0 0 11 0,这种方法对非0元素少时比较方便,不必将所有的0都写出来,只需输入少量数据。也可以只对某几行元素赋初值: in
15、t a34=1,5,6; 数组元素为 1 0 0 0 5 6 0 0 0 0 0 0 第3行不赋初值。也可以对第2行不赋初值: int a34=1,9; (4) 如果对全部元素都赋初值(即提供全部初始数据),则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。如 int a34=1,2,3,4,5,6,7,8,9,10,11,12;,可以写成 int a4=1,2,3,4,5,6,7,8,9,10,11,12; 系统会根据数据总个数分配存储空间,一共12个数据,每行4列,当然可确定为3行。 在定义时也可以只对部分元素赋初值而省略第一维的长度,但应分行赋初值。如 int a4=0,0,3
16、,0,10; 这样的写法,能通知编译系统: 数组共有3行。数组各元素为 0 0 3 0 0 0 0 0 0 10 0 0 C+在定义数组和表示数组元素时采用a这种两个方括号的方式,对数组初始化时十分有用,它使概念清楚,使用方便,不易出错。,例5.4 将一个二维数组行和列元素互换,存到另一个二维数组中。例如 a= 1 2 3 b= 1 44 5 6 2 53 6 程序如下: #include using namespace std; int main( ) int a23=1,2,3,4,5,6;int b32,i,j;,5.3.4 二维数组程序举例,coutarray a:endl;for (
17、i=0;i=1;i+)for (j=0;j=2;j+) coutaij ;bji=aij;coutendl;coutarray b:endl;for (i=0;i=2;i+)for(j=0;j=1;j+)coutbij ;coutendl; return 0; ,运行结果如下:array a:1 2 34 5 6array b:1 42 53 6,例5.5 有一个34的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。 开始时把a00的值赋给变量max,然后让下一个元素与它比较,将二者中值大者保存在max中,然后再让下一个元素与新的max比,直到最后一个元素比完为止。max最后的值就是数组所有元素中的最大值。 程序如下: #include using namespace std; int main( ) int i,j,row=0,colum=0,max;int a34=5,12,23,56,19,28,37,46,-12,-34,6,8;max=a00; /使max开始时取a00的值,