1、第 5 章 数组大家在前面的章节中已经碰到过这样的例子:求两个整数中的较小的那个,或者求三个整数中的最小数。那么大家想一下,如果题目中要求大家找出 10 个整数中的最小数呢,甚至 100 个整数中的最小数呢?在计算机应用领域中,也常常遇到这类处理大量数据的问题,其特点也是:数据量很大,数据之间存在一定的内在关系。那么,对于这样的一组数据,计算机如果用前面讲过的简单变量来处理就很不方便,甚至不能处理。考虑上面的求出 10 个整数中的最小数,先要设 10 个变量 a1,a2,a3a10,然后这 10 个变量之间又要相互比较,求出最小数。显然是非常麻烦,要是成千上万个数据,是不是还要设一万个变量呢?
2、为了解决这一问题,C 语言引入了一个重要的数据结构数组,它是具有相同数据类型的变量集合,这些变量具有相同的名字,但用不同的下标表明数据的位置,我们称这些变量为数组元素。将数组与循环结合起来,可以有效地处理大批量的数据,大大提高了工作效率,十分方便。本章介绍在 C 语言中怎样定义和使用数组,包括一维数组,二维数组和字符串。5.1 一维数组5.1.1 一维数组的定义和引用例 5-1 要求从键盘中输入 10 个互不相同的整数,求其中的最小数并输出。10 #include “stdio.h“20 main()30 40 int a10; /*定义数组 a*/50 int i,min; /*定义变量 i
3、 和 min*/60 for(i=0;iai) 130 min=ai; /*比较 min 与数组中的每个数的大小,将较小的赋给 min */140 printf(“The min is %dn“,min); /*输出最小值*/150 该程序的流程图如图 5-1 所示。开始i = 0输入 a i i a i m i n = a i 是否输出 m i n结束图 5-1 例 5-1 的流程图运行结果:45 12 89 3 56 47 15 6 7 9 45 12 89 3 56 47 15 6 7 9The min is 3 程序说明:(1)行号为 40 的语句“int a10;”是数组的定义。表示
4、定义一个名为 a 的数组,其中这个数组里包含 10 个元素,均为整型。(2)行号为 70,90,100,120 和 130 的语句都是对该数组的引用。1一维数组的定义在 C 语言中使用数组必须先进行定义。一维数组的定义方式为:类型说明符 数组名 常量表达式;其中:(1)类型说明符是任一种基本数据类型或构造数据类型,即 int、float、char 等这些基本数据类型。从这里可以看出,数组是建立在基本数据类型的基础之上的,因此数组为构造类型。在上面的例子中 int 表示数组元素为整型数据。(2)数组名是用户定义的数组标识符。对于数组元素来说,具有一个共同的名字,即数组名,用标识符表示,上面例子中
5、 a 为一维数组名。(3)方括号中的常量表达式表示数据元素的个数,也称为数组的长度。例如:float b10,c20; 定义实型数组 b,有 10 个元素,实型数组 c,有 20 个元素。char ch20; 定义字符数组 ch,有 20 个元素。对于数组定义应注意以下几点:(1)数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。(2)数组名不能与其它变量名相同。例如:main()int a;float a10;是错误的。(3)方括号中常量表达式表示数组元素的个数,如 a5表示数组 a 有 5 个元素。但是其下标从 0 开始计算。因此 5 个元素分别为 a
6、0,a1,a2,a3,a4。(4)不能在方括号中用变量来表示元素的个数, 但是可以是符号常数或常量表达式。例如:#define D 5main()int a3+5,b4+D; /*合法的定义*/但是下述说明方式是错误的。main()int n=10;int an; /*不合法的定义,n 为变量*/2.一维数组元素的存储每个数组元素都占用内存中的一个存储单元,每个元素都是一个变量,可以像以前讲过的普通变量一样使用,只不过数组元素是通过数组名和方括号“”里的下标来确定的。系统为数组元素在内存中分配连续的存储单元。 例如:定义语句 int a15;说明了以下几个问题:(1)数组名为 a。 (2)数组
7、元素的数据类型为 int 整型数据。(3)数组元素的下标值从 0 开始。数组元素的个数为 15 个,它们是:a0、a1、a2 . .a13、a14(4)数组名 a 是数组存储区的首地址,即存放数组第一个元素的地址。 aa10=4;是错误的。例 5-2 有等差数列 an=3n,要求输出 an的所有值,并求出数列的和。n 为 0 到 9 的整2000200220042006202620282030a0a1a2a3a12a13a14数。#include “stdio.h“main()int a10; /*定义数组 a*/int n,sum=0; /*定义变量 n 和 sum*/for(n=0;nai
8、+1) temp=ai; ai=ai+1; ai+1=temp;761042671042671042674102674210(2)第二趟(如图 5-5 所示) ,经过 3 次比较。经过第一趟后最大数 10 已经沉到底了,第二趟就对余下的四个数(6-7-4-2)按上述的方法,经过三次比较,得到次大的数。次大的数 7“沉底” ,最小数 2 又向上“浮起”一个位置(冒第二个泡) ,结果得到:6-4-2-7 的顺序。第 1 次 第 2 次 第 3 次 第二趟结果a0a1a2a3(a) (b) (c) (d)图 5-5 冒泡排序第二趟过程这趟比较的代码跟第一趟几乎一样,不一样的是比较的次数不一样,那就是循环次数不一样,这趟循环 3 次。用循环语句实现如下:for(i=0;iai+1) temp=ai; ai=ai+1; ai+1=temp;(3)第三趟(如图 5-6 所示) ,经过 2 次比较。对余下的三个数(6-4-2)按上述方法,经过两次比较,得到第三大数 6“沉底” ,最小数 2 又“浮起”一个位置(冒第三个泡) 。第 1 次 第 2 次 第三趟结果 a0a1a2(a) (b) (c) 图 5-6 冒泡排序第三趟过程这趟比较代码同上类似,循环次数变成 2 次。(3)第四趟(如图 5-7 所示) ,经过 1 次比较。6742674264726427642462426