1、在线教务辅导网:在线教务辅导网:http:/教材其余课件及动画素材请查阅在线教务辅导网教材其余课件及动画素材请查阅在线教务辅导网QQ:349134187 或者直接输入下面地址:或者直接输入下面地址:http:/第第7 7章章 数组数组第7章 数组本章主要内容本章主要内容1.1.一维数组的概念一维数组的概念2.2.二维二维( (多维多维) )数组的概念数组的概念3.3.字符数组的概念字符数组的概念4.4.数组作为函数参数的作用数组作为函数参数的作用5.5.不同类型数组的区别不同类型数组的区别第7章 数组程序设计遇到的问题:程序设计遇到的问题: 处理大量具有相同数据类型数据时遇到不方便。处理大量具
2、有相同数据类型数据时遇到不方便。 如:计算Fibonacci数列前40个元素的值;统计50个商品的平均价格等等。 问题具有的特性:数据类型相同。 现有的解决方案:采用简单变量的方式。 现有方案的缺陷: 需要大量不同的标识符作为变量名; 变量在内存中的存放是随机的; 随着这种变量的增多,组织和管理好这些变量会使程序变得复杂。 改进的解决改进的解决方案:方案:使用数组。使用数组。第7章 数组数组具有的特点数组具有的特点1数组是一种变量的集合,在这个集合中,所有变量的数据类型都是相同的;2每一个数组元素的作用相当于简单变量;3同一数组中的数组元素在内存中占据的内存空间是连续的;4数组的大小(数组元素
3、的个数)必须在定义时确定,在程序中不可改变;5数组名代表的是数组在内存中的首地址。7.1 一维数组的定义和初始化7.1.1 一维数组的定义一维数组的定义 一维数组的定义格式:一维数组的定义格式: 存储类型存储类型 数组大小数组大小; 如:int a6; 说明:说明: 数组名为a; 数组有6个元素:a0、a1、 a2、 a3、 a4、 a5。 每个元素都代表着一个整型变量。 数组在内存中是按顺序连续存放的,占用的内存大小为每一个元素占用内存的大小的和。7.1 一维数组的定义和初始化使用数组时要注意的几个方面:使用数组时要注意的几个方面: C语言对数组的下标值是否越界不做检测。语言对数组的下标值是
4、否越界不做检测。 如有数组int score6,数组score的下标值为05。 若在程序中使用了score6或其他下标值,程序仍会运行,但有可能出现意外情况。 数组不能整体输入或整体输出。数组不能整体输入或整体输出。 只能对其数组元素进行输入和输出。只能对其数组元素进行输入和输出。7.1 一维数组的定义和初始化例例1 1:阅读程序,通过程序的运行结果,了解一维简单数组的输入和输出。程序:程序:example7_1.c结论:结论:为确保程序的正确性,要求使用的数组元素与定义的大小要相符合。如第1组的输入输出情况;对于超出数组大小范围的非数组元素,程序并未检查其合理性,其结果是无法预料的。如第2组
5、的输入输出情况;如果对超出数组大小的非数组元数输入合理的值,表面上看输出的结果也是正确的,但实际上系统已经出现了问题,程序会非正常结束。如第3组的输入输出情况。特别提示:特别提示: 使用数组的时候,要注意数组元素的合法性。7.1 一维数组的定义和初始化7.1.2 一维数组的初始化一维数组的初始化初始化数组格式:初始化数组格式:static 数组名数组名=;或: 数组名数组名=;例如例如: int a5 =2, 4, 6, 8,10;或:int a =2, 4, 6, 8,10; 数组元素:a0=2,a1=4,a2=6,a3=8,a4=10。 static int b5 =2, 4, 6, 8,
6、10;或:static int b =2, 4, 6, 8,10; 数组元素:b0=2 b1=4 b2=6 b3=8 b4=10存储类行为自动型:存储类行为自动型:auto7.1 一维数组的定义和初始化初始化数组元素时,初始化数组元素时,如果如果元素初值个数元素初值个数 数组的长度,数组的长度,有可能出现下面两种情况:有可能出现下面两种情况:自动存储类型: 未给定的数组元素的值不能确定。 例如:例如:int c5 =1, 3, 5; 则:c0=1,c1=3,c2=5。 c3和c4的值不能确定。静态存储类型: 数值型数组和字符型数组有所不同: 例如:例如:static int d5 =11, 3
7、3, 55; 则:d0=11,d1=33,d2=55,d3=0,d4=0。 而:static w5=A,B,C; 则:w0=A,w1=B,w2=C,w3=w4=NULL。7.2 一维数组的使用数组元素的引用: 数组名数组名下标下标数组元素的作用等同于简单变量。如有:如有:int a5=1,2,3,4,5,b5=2,4,6,8,10,c3=1,2,3;int a5=1,2,3,4,5,b5=2,4,6,8,10,c3=1,2,3;char w4=char w4=a, b, c, d,;则下面的语句是合法的:则下面的语句是合法的: a3=28; b4=a2+a3; w3= d; c2=c4%2;
8、printf(%d, a0);7.2 一维数组的使用数组元素引用的说明下标可以是整数或整型表达式,若i,j均为整型变量,则下面的数组使用是合法的。 vari+j=2; str1+2= e;下标的值不应超过数组的大小,如数组a的大小为5,则下标的取值在04的范围内。 再次提醒:再次提醒: C编译不检查下标是否“出界”。 对于数组:int var5,如果使用var5,系统不报错,会把var4下面一个单元中的内容作为var5引用,如图所示。7.2 一维数组的使用例例2 2:阅读下面的程序,了解一维数组各元素的基本应用情况。程序:程序:exampple7_2.c例例3 3:编写程序,计算出fibona
9、ci数列前20项的值,将计算结果保存到数组FBNC中。并将其输出到屏幕上,每行5项,一共4行。分析:分析:本例求解的问题与例6-8类似,用整型数组FBNC20保存数列;fibonaci数列的组成规律为: FBNC0=0 FBNC1=1 FBNCi= FBNCi-1+ FBNCi-2 (i=2,3,n) 从第三项开始的,每个数据项的值为前两个数据项的和。程序:程序:example7_3.c7.3 多 维 数 组7.3.2 二维数组的定义二维数组的定义二维数组的定义格式为: 数组名行元素个数列元素个数 ;例如:例如:char word32; int num24; float term43; 数组元
10、素的下标从0开始,数组word中的元素为: word00 word01 word10 word11 word20 word21二维数组的存放顺序:按行优先,先行后列。数组word在内存中的存放顺序如图所示:word00 word01 word10 word11 word20 word21 第 1 行 第 2 行 第 3 行 7.3 多 维 数 组根据数组的下标值可以算出各元素在内存中的排列顺序。设有一个mn的二维数组amn,aij在数组中的位置为: in+j+1; ( i=0,1,2,m1,j=0,1,n1) 例如:例如:数组a43: 则:元素a21在数组中的排列位置为:23+1+1=8。 即
11、a21在存储序列中排在第8位; 如果视其为一维数组,则下标值为7。000102101112202122303132aaaaaaaaaaaaa轾犏犏犏=犏犏犏犏臌7.3 多 维 数 组数组a的元素在内存的存储顺序:数组 a 的元素 排列位置(从 1 算起) 下标值(从 0 算起) a00 1 0 a01 2 1 a02 3 2 a10 4 3 a11 5 4 a12 6 5 a20 7 6 a21 8 7 a22 9 8 a30 10 9 a31 11 10 a32 12 11 7.3 多 维 数 组7.3.3 多维数组的定义多维数组的定义多维数组的定义格式为: 数组名下标1下标2下标n;注:注
12、:下标值表示元素的个数。多维数组的存储顺序按下标从左到右的变化顺序。可以像对待一维数组那样来处理多维数组。例如:例如: float V2232; 共有24个元素 int Tel323; 共有18个元素7.3 多 维 数 组Tel数组Tel323的元素为:Tel000 Tel001 Tel002Tel010 Tel011 Tel012Tel100 Tel101 Tel102Tel110 Tel111 Tel112Tel200 Tel201 Tel202Tel210 Tel211 Tel212Tel数组在内存中的存放顺序:Tel000 Tel001 Tel002 Tel010 Tel011 Tel
13、012 Tel100 Tel101 Tel102 Tel110 Tel111 Tel112 Tel200 Tel201 Tel202 Tel210 Tel211 Tel212 7.3 多 维 数 组example7_4.c程序的功能:程序的功能: 向一个具有向一个具有3行行4列列的二维数组的二维数组a 34输入数值并输出全输入数值并输出全部数组的元素。部数组的元素。例例4 4:阅读程序,了解多维数组元素的输入/输出方法。#include main() int i,j; int a34; printf(Please input value of a (a00a23):n); for (i=0;i
14、3;i+) for (j=0;j4;j+) scanf(%d,&aij); printf(The value of a is:n); for (i=0;i3;i+) for (j=0;j4;j+) printf(a%d%d=%dt,i,j,aij); printf(n); 7.3 多 维 数 组7.3.4 二维数组及多维数组的初始化二维数组及多维数组的初始化赋初值时可采用对元素全部赋值全部赋值和部分赋值部分赋值两种方式。1对全部元素赋初值对全部元素赋初值两种赋初值格式: 分行赋值方式; 按顺序赋值方式。以二维数组array32为例,赋初值格式为: array32 a1, a2, a3, a4,
15、 a5, a6; 分行赋值 array 32 a1, a2, a3, a4, a5, a6; 按顺序赋值 array 2 a1, a2, a3, a4, a5, a6; 按顺序赋值7.3 多 维 数 组例如:例如: int array 32=1,2, 3, 4, 5, 6; 分行赋值 int array 32= 1,2, 3, 4, 5, 6; 按顺序赋值 int array 2= 1,2, 3, 4, 5, 6; 按顺序赋值上面3种对数组array元素赋初值的结果相同。数组元素在内存中的排列顺序如图所示:数组元素在内存中的顺序 数组元素的值 array00 1 array01 2 array
16、10 3 array11 4 array20 5 array21 6 7.3 多 维 数 组2对部分元素赋初值对部分元素赋初值赋初值格式: array32=a1, a2,a3; 分行赋值 array32= a1, a2, a3; 按顺序赋值例如:例如:static int array 32=1, 2,3; 分行赋值 static int array 32= 1, 2, 3; 按顺序赋值上面两种对数组array部分元素赋初值的结果是相同的。 数组array的前面3个元素赋了初值; 后面3个元素未赋初值; 系统自动赋予0值(static型)。数组array中各元素的值为:array 00=1;ar
17、ray 01=2; array 10=3;array 11=0;array 20=5;array 21=6;7.4 字 符 数 组字符串”是指若干有效字符的序列,用双引号()括起来。C语言中的字符串可以包括字母、数字、专用字符、转义字符等。例如:例如: “Hello”、“C_Language”、“ax+b=c”、“78.6”、%fn“都是合法的字符串特别提示:C语言中并没有字符串变量。 C语言程序中处理字符串,要借用字符数组来完成。 将字符串的每一个字符保存在一个字符型数组中。作为字符数组,存放字符和存放字符串在输入/输出等方面会有一些不同。7.4 字 符 数 组例如:例如:char word
18、12;word是一个字符数组,可存放最多12个字符的字符串。要用word这个数组来存放“C_Language”10个字符。可以采用赋值语句,将字符一个一个地赋予字符数组元素,如:word0= C; word1= _;word2= L; word3= a;word4= n; word5= g;word6= u; word7= a;word8= g; word9= e;如果要输出数组的内容,不能整体输出不能整体输出,而需采用循环的方式将数组元素的值输出。word10和word11的值无法预知。7.4 字 符 数 组C语言规定:语言规定:用字符0作为字符串的结束标志。对上面的数组:char word
19、12;如已赋值:word0= C; word1= _;word2= L; word3= a;word4= n; word5= g;word6= u; word7= a;word8= g; word9= e;再加上一条语句:word10= 0;则:数组word中的内容就可以作为字符串字符串整体输出: printf(%s, word);7.4 字 符 数 组比较如图所示字符数组中字符和字符串的存储方式:Word0 C Word0 C Word1 Word1 Word2 L Word2 L Word3 a Word3 a Word4 n Word4 n Word5 g Word5 g Word6 u
20、 Word6 u Word7 a Word7 a Word8 g Word8 g Word9 e Word9 e 未知值 Word10 0 未知值 未知值 (a) 字符数组 (b)字符串 7.4 字 符 数 组7.4.1 字符数组的初始化字符数组的初始化有两种初始化的方法。逐一为数组中各元素指定初值字符,即分别对每个元素赋初值。例如: char word10= C, _, L, a, n, g, u, a, g, e;或 char word=C, _, L, a, n, g, u, a, g, e;将字符串赋给指定的数组,例如: char word=C_language;或 char word
21、11=C_Language; char word11= C_Language; char word=C_Language;7.4 字 符 数 组7.4.2 字符串的输入字符串的输入字符串的输入方法:初始化字符数组;用输入函数。用用scanf()scanf()函数:函数:假定有:char name9 ;(1)向数组元素name0输入一个字符: scanf(%c, & name0);(2)向数组输入整个字符串: scanf(%s, name);或: scanf(%s,&name);注意:数组名代表数组的首地址。对一维字符数组name,输入时可直接用:scanf(%s ,name);7.4 字 符
22、数 组使用scanf函数输入字符串时需注意:输入的字符串中不能包含有空格;输入字符串时两边不要用双引号括起来。假如有: char name9 ; scanf(%s, name);若有输入: China word 结果:结果: 只把“China”作为字符串输入了数组。 数组name中的字符如图所示。注意:name6name8的值未知。name0 C name1 h name2 i name3 n name4 a name5 0 7.4 字 符 数 组 scanf()()函数的缺陷:函数的缺陷: 不能完整地读入含有空格、制表符等字符的字符串。解决方案:用解决方案:用gets()()函数。函数。 g
23、ets()函数可读入包括有空格、制表符 等全部字符。以换行符作为结束。例如有:例如有:char name9; gets(name);若输入:若输入:Very hot结果:结果: 数组name的元素如图所示。name0 V name1 e name2 r name3 y name4 name5 h name6 o name7 t name8 0 7.4 字 符 数 组若有:char name125,name225;scanf(%s%s,name1,name2);printf(name1=%s,name2-%sn,name1,name2);gets(name1);puts(name1);输入:Ch
24、ina HongKong输出结果会是怎样的?为什么?思考思考要注意字符串输入函数的特点要注意字符串输入函数的特点7.4 字 符 数 组7.4.3 字符串的输出字符串的输出printf()函数输出数组元素或存放在字符数组中的字符串。若数组name各元素的值为:若:printf(%c, %s, name0, name);输出结果为: V,Veryputs(),字符串输出函数。 可输出字符串中的空格。若:puts(name);输出结果为: Very hot name0 V name1 e name2 r name3 y name4 name5 h name6 o name7 t name8 0 7.
25、4 字 符 数 组例例5 5: 阅读程序example7_5.c ,了解用不同的方式输入/输出字符串的方法。了解规则了解规则7.4 字 符 数 组7.4.4 二维字符数组二维字符数组可将二维字符数组看成是多个一维数组。一个mn的二维字符数组可以存放m个字符串,每个字符串最大长度为n1(最后一个存放结束标志“0”)。例如:例如:char week74= SUN, MON, TUE, WED, THU, FRI, SAT;二维字符数组week可以看成是7个一维字符数组。7.4 字 符 数 组week 0 S U N 0 week 1 M O N 0 week 2 T U E 0 week 3 W
26、E D 0 week 4 T H U 0 week 5 F R I 0 week 6 S A T 0 如果要输出“MON”这个字符串,可使用下面的语句: printf(%s, week 1);其中,week1相当于一维数组名,week 1是字符串“MON”的起始地址,也就是二维数组第2行的起始地址(注意行数的起始下标值为0)。7.4 字 符 数 组例例6 6:阅读程序example7_6.c,了解二维字符数组与一维数组的关系。了解规则了解规则7.4 字 符 数 组字符串处理函数字符串处理函数 C语言提供的字符串处理库函数,主要放在头文件string.h中。常用的字符串处理库函数有:字符串拷贝函
27、数字符串拷贝函数strcpy功能:将一个字符串复制到一个字符数组中。例如:strcpy(name1, Apple);作用:将字符串复制到数组name1中,并在串尾加上结束标志。字符串连接函数字符串连接函数strcat功能:字符串连接。语法形式:strcat(name1, name2);其中name1,name2均为数组。结果:将name2中的内容连同结束符连接到name1数组的后面。 (去掉name1中原有的结束标志)7.4 字 符 数 组字符串比较函数字符串比较函数strcmp功能:比较两个字符是否相同。语法形式:strcmp(字符串1,字符串2);如果字符串1=字符串2,则函数值为0;如果
28、字符串1字符串2,则函数值为一个正整数;如果字符串1字符串2,则函数值为一个负整数。大小写字母转换函数大小写字母转换函数功能:把字符串中的大写字母改成小写,或把小写改成大写。小写转大写:strlwr(name) ;大写转小写:strupr(name) ; (name为字符串数组名)7.5 数组作为函数的参数7.5.1 数组元素作为函数的参数数组元素作为函数的参数数组元素的作用等同于简单变量。 如果实参为数组元素,则形参必须是简单变量。如果实参为数组元素,则形参必须是简单变量。 函数的调用属于传值传值调用方式(实参的值单向传递给形参)。7.5.2 数组名作为函数的参数数组名作为函数的参数数组名作
29、为实参,这种函数的调用方法又称为“传址”方式。 如果实参为数组名,则形参不允许为简单变量。如果实参为数组名,则形参不允许为简单变量。 函数的调用属于传址传址调用方式(实参与形参公用内存单元)。函数中形参值的改变会引起实参值的改变。7.5 数组作为函数的参数例例7: 阅读程序example7_10.c ,了解数组名作为函数参数的传值调用形式和作用。注意:注意:形参数组和实参数组共占用一段内存单元:当形参的值发生变化时,实参的值也随之发生变化。形参为数组时,可以不定义长度。例如,上面程序中的Expfun2函数可以写成:float Expfun2 (float a) 实参 形参 s0 88.5 a0
30、 s1 90.5 a1 s2 70 a2 s3 71 a3 7.5 数组作为函数的参数例例8: 编写程序,从键盘输入8种商品的价格,求这8种商品的平均价格、最高价和最低价,并将高于平均价格的商品数及价格打印出来。 分析:分析:因为衡量商品价格的数据类型是相同的,因此,可以用数组float price8来保存这8种商品的价格。模块化程序设计:将不同的功能设计成函数。程序功能:商品的价格输入、求平均价格、最高价、最低价、输出高于平均价格的商品数及价格。用数组名作为参数。各函数的功能如下:void readprice(float price )输入8种商品的价格并打印输出。float averpri
31、ce(float price )求商品的平均价格。float highprice(float price )求商品的最高价。float lowerprice(float price )求商品的最低价。void prtprice(float price )输出高于商品平均价的数量及价格。用变量average、highestP、lowestP分别表示商品的平均价格、最高价和最低价。7.5 数组作为函数的参数主程序流程图如图所示:主程序流程图如图所示:程序:程序:example7_11c 7.6 程 序 范 例例例9:编写程序,利用随机函数生成20个50以内大小的整数,存入到一个数组中,从键盘输入一
32、个整数作为关键字,用线性查找方法在数组中查找,如果输入的数在数组中存在,则输出该数在数组中的下标值;否则输出1,表示该数在数组中不存在。分析:分析:线性查找的方法,就是把数组中的每一个元素与输入的关键字作比较。线性查找的方法一般都采用循环结构来实现。本题的关键:本题的关键:用随机函数生成20个真随机数真随机数。用array20来保存随机生成的20个整数;用key表示从键盘输入的任意整数。设计线性查找函数:设计线性查找函数:int LineaFind(int a,int keyword) ;功能:功能:查找keyword是否在数组a 中,如果在,返回数组的下标值;否则返回1。程序:程序:exam
33、ple7_12.c 7.6 程 序 范 例例例10:设有如下所示的一个45矩阵:请编写程序,完成下面的功能:1所有元素的和;2属出所有大于平均值的元素。分析:分析:可以将该矩阵看成是一个二维数组。设计两个函数来完成不同的功能:计算所有元素的和:int sum_ave(int m,int n,int arr);,输出大于平均值的元素:void prt_up(int m,int n,float average,int arr)。用数组A45来代表矩阵元素的值;sum代表矩阵元素的和;ave代表矩阵元素的平均值。程序:程序:example7_13.c 26491351387120410276953A
34、-犏犏-犏= 犏犏犏犏-犏臌7.6 程 序 范 例 能否将形参中的数组arr直接定义成二维数组? 如果可以,调用函数的时候实参的表达式应该怎样?思考思考7.6 程 序 范 例例例1111:编写程序,从键盘输入字符(字符个数不大于1 200个),计算所输入的字符个数与输入的行数,并将计算结果输出到屏幕,以感叹号“!”作为输入的结束符。分析:分析:可用一个字符数组来保存所输入的字符,用变量number和lines分别代表输入的字符个数及行数。将系统功能划分成3大块,每一个功能用一个函数来实现。1将键盘输入的字符保存到数组中:void wordInput(char string)。2统计数组中的字符
35、个数number和行数lines: void countWords(char string)。3将计算结果输出到屏幕: void wordOutput(int number,int lines)。为方便起见,可将字符个数为方便起见,可将字符个数number和行数和行数lines设置成为全局变量。设置成为全局变量。程序:程序:example7_14.c 7.6 程 序 范 例例例12:编写一个模拟投票系统,有20个人要对3个人进行选举投票,要求统计每个人的得票数和弃权票数,并将结果输出到屏幕。分析:分析:可用数组int candidate4保存投票结果,candidate1candidate3分
36、别为3个不同候选人的得票数,candidate0为弃权票数;用数组int voten保存n个投票人的投票结果,投票的结果值i为对第i个人的投票(i=1,2,3),如果i为其他值(i1,2,3),则表示弃权。设计两个函数:设计两个函数:1void vInput(int n,int v):将n个人的投票结果保存到数组v中。2void prtResult(int n,int p,int v):将n个投票结果vn按候选人pi进行统计,并输出投票结果。统计投票结果的关键表达式为:+pvi,(i=0,1,2,n)。程序:程序:example7_15.c 7.6 程 序 范 例例例13: 编写程序,从键盘输
37、入一组字符串,长度不超过80个字符,以结束标志为输入结束。将该字符串的字符反向输出到屏幕。假如输入的字符串为abcdefg,则输出结果为gfedcba。分析:分析:用字符数组char strings81保存输入的字符。要注意的是,当输入结束时或是输入的字符超过规定的长度时,要将字符串的结束标志放入到数组中最后一个字符的后面,以便于下一步的处理。设计递归函数算法: void backwards(char s,int index)进行反向输出。程序:程序:example7_16.c 7.6 程 序 范 例请读者分析递归函数void backwards(char s,int index)的算法思想,
38、写出其算法表达式。非递归的算法来实现。 请设计非递归的算法,并编写程序验证。思考思考7.7 本 章 小 结本章主要内容本章主要内容1数组元素的作用和数组名的作用。2字符串的含义及处理方式。3多维数组的定义及使用方法。4数组元素在内存中的存放方式及占用内存空间的大小。5数组元素与数组名作为函数参数有什么区别。6进一步掌握结构化的程序设计方法,将系统的工作交给多个函数去处理,每一个函数的功能尽可能的单一化,便于系统的维护和扩充。习 题一、单选题二、判断题三、填空题四、阅读下面的程序,写出程序运行结果五、程序填空题。请在下面程序空白处填入合适的语句六、编程题 【题7.37】【题7.38】【题7.39】 【题7.43】【题7.46】【题7.50】