1、第 8章 数组类型 第第 8章章 数组类型数组类型 8.1 一维数组一维数组 8.2 二维数组与多维数组二维数组与多维数组 8.3 字符数组与字符串字符数组与字符串 8.4 重命名类型重命名类型 8.5 程序设计举例程序设计举例 第 8章 数组类型 8.1 一维数组一维数组 8.1.1 一维数组的定义一维数组的定义 形式:存储类别 类型标识符 数组名常量;类型标识符描述的是数组分量的类型,是定义数组类型的基类型,可以是任何类型。数组名代表数组所占存储空间的首地址。常量表示数组的大小(长度),即数组中分量的个数。与PASCAL语言不同,以上实际定义的是数组量,而非数组类型,数组类型隐含其中。提到
2、数组,可能是指数组量,也可能是指数组类型,注意根据上下文区分。第 8章 数组类型 例如,定义数组,描述下列数据:(1)100个整数:int num100;(2)1000个学生C语言课程的成绩:float ccj1000;(3)一年中每月的天数:int month12;(4)100种商品的价格:float price100;(5)500个字符类型的数据:char ch500;第 8章 数组类型 说明:(1)数组名命名规则和变量名命名规则相同,都遵循标识符命名规则。(2)数组的长度可以用符号常量描述,但不能用变量描述,C语言不提供动态数组。(3)数组以线性方式将数组分量依次存储,所占空间等于各分量
3、所占空间之和,即数组分量个数乘以基类型数据所占空间。数组名代表存放数组的首地址。第 8章 数组类型 8.1.2 一维数组的引用一维数组的引用 下标变量的形式为:数组名下标表达式 例如,对以上定义的num数组、ccj数组:num数组的100个分量为num0、num1、numi、num99,每个分量存放一个整数,numi相当于一个int型变量。ccj数组的1000个分量为ccj0、ccj1、ccji、ccj999,每个分量对应一个学生的成绩,ccji相当于一个float型变量。第 8章 数组类型 说明:(1)下标的取值范围从0到数组长度减1。(2)下标变量相当于基类型变量,能进行基类型量的一切运算
4、操作。(3)下标往往对应于循环控制变量,通过循环、通过下标的变化完成对数组所有分量的操作,即完成对整个数组的操作。(4)下标往往对应特定的含义。(5)对于下标出界,C语言不进行语法检查,务请小心。第 8章 数组类型 (6)如果希望下标为i的分量对应第i个数据,可将定义的数组大小增1。例如:int num101;float ccj1001;100个整数用num数组的分量num1、num2、num100描述,numi对应于第i个整数。1000个学生的C语言成绩用ccj数组的分量ccj1、ccj2、ccj1000描述,ccji对应于第i个学生的成绩。下标为0的分量未使用。第 8章 数组类型 8.1.
5、3 一维数组的初始化一维数组的初始化 数组的初始化可以在执行时进行,也可以在编译阶段进行。执行时初始化可通过赋值运算或赋值语句、或输入函数进行,但只能对数组分量进行,要占用运行时间。例如:输入数据给数组num、ccj。for(i=0;i101;i+)scanf(%d,&numi);for(i=0;i1001;i+)scanf(%f,&ccji);对静态存储数组和外部存储数组,数组的初始化可以在编译阶段进行,即在程序运行之前初始化,节约运行时间。第 8章 数组类型 初始化形式:存储类别 类型 数组名常量=常量1,常量2,常量n;各分量依次初始化为常量1、常量2、常量n。注意初始化数据必须用花括号
6、括起。例如:static int month12=31,29,31,30,31,30,31,31,30,31,30,31;则month0=31,month1=29,month2=31,month12=31。static char ch5=a,e,i,o,u;则 ch0=a,ch1=e,ch2=i,ch3=o,ch4=u。第 8章 数组类型 说明:(1)对静态存储数组和外部存储数组,默认初值为0。(2)可以只给一部分数组分量初始化。例如:static int a 50=70,75,60,80,90;相当于a0=70,a1=75,a2=60,a3=80,a4=90,没有给定初值的分量取默认初值。(
7、3)若对数组中所有分量给定了初值,则定义数组时可以不给出数组长度。数组的长度为给出的初值个数。例如:static float x=1.5,2.5,3.5,4.5,5.5;给了数组5个初值,则数组长度为5。(4)若仅给数组部分分量初值,则不能省略数组长度。第 8章 数组类型 例例 8 1 求10个数的最大值与最小值,10个数用数组描述。程序如下:/*程序8-1,求10个数的最大值与最小值*/main()float a10;/*存放10个数的数组*/int i;float max=1e20,min=1e20;for(i=0;i=9;i+)/*输入10个数到数组*/scanf(%f,&ai);for
8、(i=0;imax)max=ai;if(aimin)min=ai;for(i=0;i=9;i+)/*输出数组中的10个数*/printf(%8.2f,&ai);printf(n最大值=%f,最小值=%f,max,min);第 8章 数组类型 例例 8 2 求某班50个学生C语言课程的平均成绩及每个学生与平均成绩之差。算法提示:(1)50个学生C语言课程的成绩及每个学生与平均成绩之差都是大量类型相同的数据,可分别用一个一维数组作整体描述。(2)下标为0的分量没有使用,同时用下标对应学号。(3)数组的整体操作转化成对数组分量进行,其实就是将对50个学生的成绩处理转化成对每个学生进行。第 8章 数组
9、类型/*程序8-2,求C语言课程的平均成绩及每个学生与平均成绩之差*/main()float ccj51;/*C语言成绩数组*/int i;float tcj=0.0;/*总成绩*/float av,cav51;/*平均成绩av,与平均成绩之差数组cav*/*输入学生成绩*/for(i=1;i=50;i+)printf(请输入第%d个学生成绩:,i);scanf(%f,&ccji);/*求总成绩、平均成绩*/第 8章 数组类型 for(i=1;i=50;i+)tcj+=ccji;av=tcj/50;/*求与平均成绩之差*/for(i=1;i=50;i+)cavi=ccjiav;/*输出*/pr
10、intf(C语言课程的平均成绩=%5.2fn,av);for(i=1;i=50;i+)printf(第%d个学生与平均成绩之差=%5.2n,i,cavi);第 8章 数组类型 例例 8-3 用一维数组求Fibonacci数列前20项,要求每行输出5个数。/*程序8-3,求Fibonacci数列前20项*/main()static int a20=1,1;/*存放Fibonacci数列前20项的数组*/int i;for(i=2;i20;i+)fi=fi-1+fi-2;printf(Fibonacci数列前20项如下:n);for(i=2;i20;i+)printf(%8d,fi);if(i%5
11、=0)printf(n);/*if语句用来控制换行*/*程序8-3,求Fibonacci数列前20项*/main()static int a20=1,1;/*存放Fibonacci数列前20项的数组*/int i;for(i=2;i20;i+)fi=fi-1+fi-2;printf(Fibonacci数列前20项如下:n);for(i=2;i20;i+)printf(%8d,fi);if(i%5=0)printf(n);/*if语句用来控制换行*/第 8章 数组类型 运行结果:Fibonacci数列前20项如下:1 1 2 3 5 8 13 21 34 55 89 144 233 377 61
12、0 987 1597 2584 4181 6765 第 8章 数组类型 8.1.4 一维数组作函数参数一维数组作函数参数 数组作函数参数有数组元素作函数参数和整个数组作函数参数两种情况。数组元素作函数参数只能是作函数的实参,与基类型变量作函数一样处理。整个数组作函数参数,此时实参与形参都应用数组名或后介绍的指针量,而且基类型应该一致。整个数组作函数参数,传递的是数组的首地址,即将实参数组的首地址传递给形参数组,形参数组与实参数组共享存储单元。在函数中改变了形参数组的值,实参数组将同时改变,因而数据是双向传递的。第 8章 数组类型 例例 8-4 将例8-2中求C语言课程平均成绩改用函数实现。函数
13、如下:float avf(xcj)/*求C语言课程平均成绩*/float xcj51;int i;float sum=0.0,tav;for(i=1;i=50;i+)sum+=xcji;tav=sum/50;return(tav);第 8章 数组类型 主函数中调用函数avf()来求平均成绩:av=avf(ccj);此时,实参数组为ccj,对应的形参数组为xcj,调用时将实参数组ccj首地址传递给形参数组xcj。请注意本例中数组的第一个分量ccj0、xcj0无意义。对形参数组可以不指定数组大小,在定义数组时数组名后跟空的中括号。在函数中另设一个参数,传递数组元素的个数。如此在函数中实现变相动态数
14、组。第 8章 数组类型 例例 8-5 将上例中函数延伸考虑为求n个学生C语言课程平均成绩。函数如下:float avf(xcj,n)/*求n个学生C语言课程平均成绩*/float xcj,n;int i;float sum=0.0,tav;for(i=1;i=n;i+)sum+=xcji;tav=sum/n;return(tav);第 8章 数组类型 例例8-2 求50个学生C语言课程平均成绩可用如下函数调用:av=avf(ccj,50);最后请注意一点,C语言编译系统对形参数组大小不作检查。如果形参数组小于实参数组,这时形参数组得到实参数组的部分值。如果希望形参数组得到实参数组的全部值,则应
15、指定形参数组不小于实参数组。第 8章 数组类型 8.2 二维数组与多维数组二维数组与多维数组 8.2.1 二维数组的定义二维数组的定义 形式:存储类别 类型标识符 数组名常量1常量2;n维数组的定义形式:存储类别 类型标识符 数组名常量1常量2常量n;类型标识符描述的同样是数组分量的类型,是定义数组类型的基类型,它可以是任何类型。数组名代表数组所占存储空间的首地址。常量分别表示数组相应维的大小,数组分量个数等于常量1、常量2、常量n之积。第 8章 数组类型 (1)上述100个班,每班50个学生一门课程的成绩,定义如下二维数组描述:float cj10050;/*第一维对应班级,第二维对应学生*
16、/(2)1000个学生,30门课程的成绩,定义如下二维数组描述:float acj100030;/*第一维对应学生,第二维对应课程*/(3)上述某高校社会实践调查数据,定义如下三维数组描述:int b323;/*第一维对应年级,第二维对应性别,第三维对应交通工具*/第 8章 数组类型 说明:(1)二维数组相当于用一张表格描述数据,第一维对应表格的行,第二维对应表格的列。(2)二维数组以线性代数中的矩阵作为典型数学背景,矩阵在程序中用二维数组描述。(3)二维数组还可看成由一维数组拓展而来,相当于一个基类型为一维数组的一维数组。例如,二维数组cj相当于基类型为float x50、具有100个分量的
17、一维数组。第 8章 数组类型 (4)对于多维数组,同样可看成由低维数组拓展而来。(5)多维数组同样将数组各分量依次连续存储,即按下标1、下标2、下标n存储,所占空间等于各分量所占空间之和,即数组分量个数乘以基类型数据所占空间。对于二维数组,也就是按行、按列存储。数组名代表存放数组的首地址。第 8章 数组类型 8.2.2 二维数组的引用二维数组的引用 二维数组下标变量的形式为:数组名下标表达式1下标表达式2多维数组下标变量的形式为:数组名下标表达式1下标表达式2下标表达式n例如,以上定义的acj数组的3000个分量为:acj00、acj01、acj029acj10、acj11、acj129,ac
18、j9990、acj9991、acj99929 第 8章 数组类型 说明:(1)每个下标的取值范围从0到数组长度减1,下标变量同样相当于基类型变量。(2)对于多维数组整体操作的完成需用多重循环,一个下标对应于一重循环控制变量。二维数组的整体操作用两重循环完成,外重循环对应下标1,内重循环对应下标2。(3)其它类似于一维数组处理。第 8章 数组类型 8.2.3 二维数组的初始化二维数组的初始化 初始化形式:存储类别 类型 数组名下标1下标2=常量1,常量2,常量n;例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12;初始化的结果是:a00=1,a01=2,a0
19、2=3,a03=4,a10=5,a11=6,a12=7,a13=8,a20=9,a21=10,a22=11,a23=12 第 8章 数组类型 说明:(1)二维数组的初始化可以分行进行。例如,上面的a数组初始化还可以表示为:static int a34=1,2,3,4,5,6,7,8,9,10,11,12;而定义4行3列的b数组可以表示为:static int b43=1,2,3,4,5,6,7,8,9,10,11,12;第 8章 数组类型 (2)可以只对数组中部分分量进行初始化。例如:static int a34=1,2,5,9;初始化的结果是:a00=1,a01=2,a10=5,a20=9,
20、其它分量初值取默认值,为0。第 8章 数组类型 (3)如果对二维数组中全部元素初始化,则定义数组时第一维的长度可以省略,但第二维的长度不能省略。例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12;可以写成 static int a 4=1,2,3,4,5,6,7,8,9,10,11,12;但不能写成 static int a =1,2,3,4,5,6,7,8,9,10,11,12;因为两个维数都省略时,可以理解为1*12、12*1、3*4、4*3、2*6、6*2等多种形式,会发生混淆,故只能省略第一个维数。第 8章 数组类型 (4)如果对二维数组按行进行初
21、始化,则定义数组时第一维的长度也可以省略。例如:static int a 4=1,2,5,9;二维数组与多维数组作函数参数跟一维数组作函数参数类同处理,但对形参数组,只有第一维的大小可以省略,第二维及其它高维的大小均不能省略。第 8章 数组类型 例例 8-6 从键盘输入50个学生8门课程成绩,求每个学生的总成绩与平均成绩。/*程序8-6,求总成绩及平均成绩*/main()float cj519;int i,j;float tcj51,acj51;void tcjf();void acjf();for(i=1;i=50;i+)/*输入成绩*/printf(请输入第%d个学生8门课程成绩:,i);
22、for(j=1;j=8;j+)scanf(%f,&cjij);第 8章 数组类型 tcjf(cj,tcj);/*调用函数tcjf()求总成绩*/acjf(tcj,acj);/*调用函数acjf()求平均成绩*/printf(所求学生总成绩与平均成绩如下:n);/*输出处理结果*/for(i=1;i=50;i+)printf(第%d个学生总成绩=%6.2f,平均成绩=%5.2fn,tcji,acji);第 8章 数组类型 void tcjf(xcj,xtcj)/*求总成绩函数*/float xcj519,xtcj51;int i,j;for(i=1;i=50;i+)for(xtcji=0.0,j
23、=1;j=8;j+)xtcji+=xcjij;void acjf(xtcj,xacj)/*求平均成绩*/float xtcj51,xacj51;int i;for(i=1;i=50;i+)xacji=xtcji/8;第 8章 数组类型 例8-7 编写程序,计算两个34的整数矩阵之和。算法提示:(1)两个34的矩阵用两个二维数组a、b描述。(2)和亦是一个34的矩阵,同样用一个二维数组c描述。(3)和矩阵元素等于矩阵对应元素之和。第 8章 数组类型/*程序8-7,求两个34的矩阵之和*/main()int a34,b34;int i,j;int c34;for(i=0;i3;i+)/*输入矩阵a
24、*/for(j=0;j4;j+)scanf(%d,&aij);for(i=0;i3;i+)/*输入矩阵b*/for(j=0;j4;j+)scanf(%d,&bij);for(i=0;i3;i+)/*计算矩阵c*/for(j=0;j4;j+)第 8章 数组类型 cij=aij+bij;printf(所求和矩阵为:n);for(i=0;i3;i+)/*输出矩阵c*/for(j=0;j=0&linei=a&linei=A&linei=Z)num1+;else num2+;printf(数字字符数=%d字母字符数=%d其它字符数=%d,num0,num1,num2);第 8章 数组类型 例例8-10
25、求80个字符串中的最大者。算法提示:(1)80个字符串用二维字符数组str描述。(2)字符串最大者的求法与求最大值的方法完全相同,但比较、赋值操作需用函数strcmp()、strcpy()完成。第 8章 数组类型 程序如下:程序如下:/*程序8-10,求80个字符串中的最大者*/main()char str8021;/*假定字符串的最大长度不超过20个字符*/int i;char mstr21;/*存放最大者*/for(i=0;i80;i+)gets(stri);strcpy(mstr,str0);/*最大者初始化为第一个字符串*/for(i=1;i0)strcpy(mstr,stri);pr
26、intf(字符串中的最大者=%s,mstr);第 8章 数组类型 8.4 重重 命命 名名 类类 型型 8.4.1 重命名类型的方法重命名类型的方法 一般形式:typedef 已有类型 新类型名;一旦重命名类型,就可以用新类型名来描述数据。习惯上新类型名用大写字母表示。例如:typedef int integer;/*重命名整型integer*/integer i,j;/*定义整型变量i、j*/typedef int COUNT;/*命名一计数类型COUNT*/COUNT n1,n2;/*定义计数型变量n1、n2*/第 8章 数组类型 typedef int NUM100;/*命名一整型数组类
27、型NUM*/NUM n;/*定义NUM型数组n*/typedef char STRING81;/*命名一字符串类型STRING*/STRING str1,str2;/*定义STRING型变量str1、str2*/typedef struct int day;int month;int year;DATE;/*命名一结构体类型DATE*/DATE date1,date2;/*定义DATE型变量date1、date2*/第 8章 数组类型 8.4.2 重命名类型的作用重命名类型的作用 重命名类型的作用如下:(1)有利于加强数据描述的针对性,增加程序的可读性。如用上面的重命名类型COUNT来定义计数
28、器变量,用途一目了然。第 8章 数组类型 (2)有利于程序的通用和移植。C语言程序设计有时可能会依赖于具体的计算机。例如,整型数据在某种机器上可能占2字节内存单元,在另外一种机器上又可能占4字节的内存单元,若将程序从2 字节的机器移植到4字节的机器,则要将所有int说明改成long说明,修改的部分可能较多,程序的移植性较差。在整型数占2字节的机器上,若用typedef重命名类型:typedef int integer;,则可用integer定义变量。若要将程序移植到整型数占4字节的机器上,只要用long代替原来的int即可,这时可再用typedef重命名类型:typedef long inte
29、ger;。(3)有利于减少程序书写的工作量。若程序中有不少地方要用到同一种复杂数据类型,书写起来比较复杂,通过重命名类型,可减少重复劳动。第 8章 数组类型 8.4.3 几点说明几点说明 (1)用typedef只能对已有类型增加一个名字,而不能定义一个新的类型。(2)用typedef可以对各种已有类型增加新的类型名,但不能用来定义变量。(3)重命名类型可以将数组类型与数组变量分离开来。(4)重命名类型与编译预处理不同,它是在编译时处理的,实际上也并不是作简单的字符串替换。(5)常将一些常用的重命名类型单独放在一个文件中,需要时用#include指令将它们包含至程序中。第 8章 数组类型 8.5
30、 程序设计举例程序设计举例 例例8-11 求n个实数的和、积、最大值及最小值。本题的算法我们已很清楚,这里是在考察在用数组描述数据的情况下的实现。求和、积、最大值、最小值均用数组作参数的函数完成。引入数组后,最大值、最小值可用其下标来描述,先假定最大值、最小值是数组的第一个分量。第 8章 数组类型 程序如下:/*程序8-11,求n个数的和、积、最大值、最小值*/#define N 100main()float aN;int n;int i;float sf();/*函数申明*/float mf();float max();float min();scanf(%d,&n);/*输入n个数*/第
31、8章 数组类型 for(i=1;i=n;i+)scanf(%f,&ai);printf(和=%8.3fn,sf(a,n);/*输出结果*/printf(积=%8.3fn,mf(a,n);printf(最大值=%8.3fn,max(a,n);printf(最小值=%8.3fn,min(a,n);float sf(xa,xn)/*求和*/float xa;int xn;int i;float s=0;第 8章 数组类型 for(i=1;i=xn;i+)s+=xai;return(s);float mf(xa,xn)/*求积*/float xa;int xn;int i;float m=1;for(
32、i=1;i=xn;i+)m*=xai;return(m);第 8章 数组类型 float max(xa,xn)/*求最大值*/float xa;int xn;int i,k=1;/*k存放最大值下标*/for(i=2;ixak)k=i;return(xak);float max(xa,xn)/*求最小值*/float xa;int xn;int i,k=1;/*k存放最小值下标*/for(i=2;i=xn;i+)if(xaixak)k=i;return(xak);第 8章 数组类型 例例8-12 给定一个43的整数矩阵,求矩阵中最小值及最小值所在行的行号和列号。程序如下:/*程序8-12,求矩
33、阵中最小值及其位置*/main()int a43;/*存放矩阵*/int i,j;int min,row,col;/*存放最小值及最小值所在行的行号、列号*/for(i=0;i4;i+)/*输入矩阵*/for(j=0;j3;j+)scanf(%d,&aij);第 8章 数组类型 row=0;col=0;min=a00;/*初始化最小值及最小值所在行的行号、列号*/for(i=0;i4;i+)/*求最小值及最小值所在行的行号、列号*/for(j=0;j3;j+)if(aijmin)min=aij;row=i;col=j;printf(最小值为%d,处在%d行%d列,min,row,col);第
34、8章 数组类型 例例8-13 将n个实数由大到小排序。n个实数用数组a描述。本例提供用选择排序方法与冒泡排序方法分别实现n个实数由大到小排序的函数。算法一:选择排序。选择排序需反复进行求最大值与交换两个数这两种基本操作。对a0、a1、an?1由大到小排序:先求所有数的最大值,然后将最大值与a0进行交换;再求a1至an-1这些数的最大值,然后将最大值与a1进行交换;再求a2至an-1这些数的最大值,然后将最大值与a2进行交换 最后求an-2与an-1这些数的最大值,然后将最大值与an?2进行交换。如此经过n-1轮处理完成排序。第 8章 数组类型 排序函数如下:void sort1(a,n)/*选
35、择排序函数*/float a;int n;int k,i,j;/*k最大值下标,i、j循环控制变量*/float t;/*中间变量,用于两个数的交换*/for(i=0;in?1;i+)k=i;/*求最大值下标*/for(j=i+1;jak)k=j;t=ai;ai=ak;ak=t;/*进行交换*/第 8章 数组类型 算法二:冒泡排序。冒泡排序需反复进行相邻两个数的比较与交换这两种基本操作。对相邻的两个数进行比较时,如果后面的数大于前面的数,将这两个数进行交换,大的数往前冒。将所有相邻的两个数比较一遍,称为一轮比较。如果一轮比较中无交换,则排序完成。有无交换用一标志变量描述,一轮比较用for循环完
36、成,整个排序利用标志变量用条件循环控制。第 8章 数组类型 排序函数如下:void sort2(a,n)/*冒泡排序函数*/float a;int n;int i;/*一轮比较的循环控制变量*/int flag;/*标志变量,为1有交换,为0无交换*/float t;/*中间变量,用于两个数的交换*/do flag=0;/*先假定无交换,已排好序*/for(i=0;iai)t=ai;ai=ai+1;ai+1=t;/*进行交换*/flag=1;/*有交换,标志变量的值改变为1*/while(flag);第 8章 数组类型 例例8-14 筛法求21000之间的所有素数。算法提示:(1)建立筛子,在
37、这里正好利用数组作筛子,下标对应于数,相应下标变量的值标志是否在筛子中,为1表示在筛子中,为0表示已被筛去,不在筛子中。(2)找每一轮筛选种子,筛选种子是完成一轮筛选后的下一个最小的素数,初值为2。(3)对每一轮筛选种子,筛去其所有倍数,即将相应下标变量的值赋值为0。倍数初值为筛选种子的2倍。(4)筛选完成,筛子中剩下的即为素数。第 8章 数组类型 程序如下:/*程序8-14,筛法求21000之间的所有素数*/main()int a1000;/*筛子数组*/int i;int minp,double;/*minp筛选种子,double倍数*/int n=0;/*素数个数,用于输出格式控制*/f
38、or(i=2;i1000;i+)/*建立筛子*/ai=1;minp=2;/*筛选种子初始化*/while(minp500)/*完成整个筛选*/double=2*minp;/*倍数初始化*/第 8章 数组类型 while(double1000)/*完成一轮筛选*/adouble=0;/*筛去当前倍数*/double+=minp;/*计算下一个倍数*/do /*计算下一轮筛选种子*/minp+;while(aminp=0);printf(21000之间的所有素数如下:n);/*输出*/for(i=2;i1000;i+)if(ai=1)printf(%6d,i);n+;if(n%5=0)printf
39、(n);/*5个素数输出在一行*/第 8章 数组类型 例例8-15 求101000之间的回文数。算法提示:(1)要判断一个数是不是回文数,先将其数字分离,用一数组a存放,然后将相应数字进行比较。(2)引入一标志变量flag,为1表示是回文数,为0表示不是回文数。程序如下:/*程序8-15,求101000之间的回文数*/main()int i,x;int a8,j;int b,e;int flag;for(i=10;i0)aj=x%10;x/=10;j+;flag=1;/*先假定i为回文数*/b=0;e=j?1;while(bx,则查找区间缩小为0,d;如果adx)e=d;else b=d;wh
40、ile(be&!flag);if(flag=0)k=-1;/*没找到*/return(k);第 8章 数组类型 例例8-17 某班有50个学生,期终考试考了8门课程。求每个学生的总成绩及平均成绩,并按总成绩由高到低排序。算法提示:(1)每个学生包括姓名和8门课程成绩,50个学生的数据分别用二维字符数组st、二维实型数组cj描述,通过第一个下标进行关联。(2)50个学生的总成绩和平均成绩用二维实型数组tacj描述,同样通过第一个下标与其姓名、8门课程成绩进行关联。(3)排序采用冒泡排序方法。(4)整个程序由输入input()、计算总成绩及平均成绩count()、排序sort()、输出output
41、()四个模块组成。(5)使用外部数组完成数据传递。第 8章 数组类型 程序如下:/*程序8-17,成绩处理程序*/char st5112;/*采用外部数组实现数据传递*/float cj519;float tacj513;main()void input();/*函数申明*/void count();void sort();void output();input();/*调用输入函数*/count();/*调用计算函数*/sort();/*调用排序函数*/output();/*调用输出函数*/第 8章 数组类型 void input()/*输入函数*/int i,j;for(i=1;i=50;
42、i+)printf(请输入第%d个学生姓名,成绩:n,i);scanf(%s,sti);for(j=1;j=8;j+)scanf(%f,&cjij);第 8章 数组类型 void count()/*计算函数*/int i,j;for(i=1;i=50;i+)tacji1=0;for(j=1;j=8;j+)tacji1+=cjij;tacji2=tacji1/8;第 8章 数组类型 void sort()/*排序函数*/int i,flag;char ts12;float t;do flag=0;for(i=1;itacji1)strcpy(ts,sti);strcpy(stI,sti+1);s
43、trcpy(sti+1,st);/*交换姓名*/for(j=1;j=8;j+)/*交换8门课程成绩*/第 8章 数组类型 t=cjij;cjij=cji+1j;cji+1j=t;t=tacji1;tacji1=tacji+11;tacji+11=t;/*交换总成绩*/t=tacji2;tacji2=tacji+12;tacji+12=t;/*交换平均成绩*/flag=1;while(flag);第 8章 数组类型 void output()/*输出函数*/int i;printf(50个学生成绩处理结果如下:n);printf(姓名 课程1 课程2 课程3 课程4 课程5 课程6 课程7 课程
44、8 总成绩 平均成绩 名次n);for(i=1;i=50;i+)printf(%8s,sti);for(j=1;j=8;j+)printf(%7.2f,cjij);printf(%7.2f%7.2f%5d,tacji1,tacji2,i);printf(n);第 8章 数组类型 例例8-18 用递归的方法计算n个数的最大公约数和最小公倍数。算法提示:(1)定义外部数组a存放n个数,假定n不超过50。(2)先计算头两个数的最大公约数和最小公倍数;再计算求出的最大公约数和最小公倍数与第3个数的最大公约数和最小公倍数;再计算与第4个数的最大公约数和最小公倍数直至求出与最后一个数的最大公约数和最小公倍
45、数即为所求。(3)定义递归函数gysfn()计算n个数的最大公约数,递归函数gbsf()计算n个数的最小公倍数。其中都调用求两个数的最大公约数函数gysf2()。(4)主函数中仅进行n个数的输入和计算结果的输出。第 8章 数组类型 程序如下:/*例8-18,用递归的方法计算n个数的最大公约数和最小公倍数*/int n,a50;/*数组a存放n个数*/int gysf2();/*计算两个数的最大公约数*/int gysfn();/*计算n个数的最大公约数*/int gbsf();/*计算n个数的最小公倍数*/main()int i;clrscr();printf(输入数的个数:);scanf(%
46、d,&n);for(i=0;in;i+)printf(输入第%d个数:,i);scanf(%d,&ai);printf(nn);第 8章 数组类型 printf(最大公约数=%d n,gysfn(a0,a1,0,n-1);printf(最小公倍数=%d n,gbsf(a0,a1,0,n-1);int gysf2(m,n)/*计算两个数的最大公约数*/int m,n;int t,r;if(mn)t=m;m=n;n=t;r=m%n;while(r!=0)m=n;n=r;r=m%n;return(n);第 8章 数组类型 int gysfn(n1,n2,b,e);/*计算n个数的最大公约数*/int
47、 n1,n2,b,e;int t;/*当前公约数*/t=gysf2(n1,n2);if(b=e)return(t);/*递归终此*/else if(b=0)b+=2;else b+;gysfn(ab,t,b,e);/*递归调用*/第 8章 数组类型 int gbsf(n1,n2,b,e);/*计算n个数的最小公倍数*/int n1,n2,b,e;int t;/*当前公倍数*/t=n1*n2/gysf2(n1,n2);if(b=e)return(t);/*递归终此*/else if(b=0)b+=2;else b+;gbsf(ab,t,b,e);/*递归调用*/第 8章 数组类型 1编写程序,将
48、10个数34、3、29、63、70、16、85、82、90、93存放于一数组中,求出这10个数的和及平均值。2编写程序,求存放于上题数组中10个数的最大值、最小值及所在位置。3编写程序,从键盘读50个数存放于一数组,求出该数组中最大值、最小值及所在位置。4将存放于上题数组中的50个数分别按升序、降序排序。5编写程序,从键盘输入某班学生C语言课程考试成绩,评定每个学生C语言成绩等级。如果高于平均分十分,则等级为优秀;如果低于平均分十分,则等级为一般;否则等级为中等。习习 题题 八八第 8章 数组类型 6某班期终考试有6门课程,编写程序计算每门课程的平均成绩。进一步考虑全年级10个班的情况。7编写
49、程序,将一个一维数组进行逆置。例如,原来顺序为1、3、5、7,则逆置后的顺序为7、5、3、1。8编写程序,打印如下的杨辉三角形。1 1 1 1 2 1 1 3 3 1 1 4 6 4 1第 8章 数组类型 9编写程序,用筛法求1001000之间的素数。10编写程序,利用数组实现大整数的加、减运算。假定大整数不超过10位数字。11编写程序,从键盘输入两个44的矩阵A和B,求出它们的和、差、积,并按矩阵形式输出。12编写程序,将一个二维数组的行列互换,并考虑用函数实现。13编写程序,找出一个二维数组中的鞍点,即该位置上的元素在该行上最大、在该列上最小。14编写程序,输入一行字符,统计其中有多少个单
50、词,单词之间用空格分隔开。第 8章 数组类型 15有一篇文章,共10行,每行有80个字符。编写程序,统计其中大写字母、小写字母、数字、空格及其它字符各有多少个。16编写程序,分别实现字符串复制函数strcpy()、字符串比较函数strcmp()的功能。17有一行电文,已按下面的规律译成密码:AZ az,BY by,CX cx,即第1个字母变成第26个字母,第i个字母变成第26?i+1个字母。非字母字符不变。编写程序将密码译回原文,并输出密码和原文。18编写程序,读入若干国家的名字,按字典顺序排序输出。第 8章 数组类型 19若A为nn对称方阵,将A压缩存放到一维数组B中,使B具有n(n+1)/