1、第5章 函数与带参数宏【教学目标教学目标】(1 1)掌握函数的概念、声明、与函数的定义)掌握函数的概念、声明、与函数的定义(2 2)掌握函数的调用)掌握函数的调用(3 3)掌握函数调用中通过虚实结合进行参数传递)掌握函数调用中通过虚实结合进行参数传递(4 4)掌握带参数宏的作用与定义)掌握带参数宏的作用与定义(5 5)掌握常用库函数和预处理语句)掌握常用库函数和预处理语句(6 6)了解库函数所在的头文件)了解库函数所在的头文件(7 7)理解函数与宏的区别)理解函数与宏的区别【内容摘要内容摘要】(1)知识点)知识点:函数的声明定义与函数的声明定义与调用调用;函数的嵌套与递归函数的嵌套与递归调用调
2、用;外部函数和内部外部函数和内部函数函数;带参数的带参数的宏宏;库函数及预处理命令库函数及预处理命令#include;函数综合应用举例函数综合应用举例(2)难点)难点:函数的调用及参数传递;带参数宏的定义与调用:函数的调用及参数传递;带参数宏的定义与调用(3)重点)重点:函数的定义、函数的调用、虚实结合进行参数传递:函数的定义、函数的调用、虚实结合进行参数传递、函数的综合利用、函数的综合利用本章节次5.12 5.12 函数声明、定义与调用函数声明、定义与调用5.2 5.2 函数嵌套与递归函数嵌套与递归5.3 5.3 内部函数和外部函数内部函数和外部函数 5.4 5.4 带参数的宏带参数的宏 5
3、.5 5.5 库函数及预处理命令库函数及预处理命令5.6 5.6 函数综合应用举例函数综合应用举例源程序文件1预编译命令说明部分执行部分函数1函数n源程序文件i源程序文件nC程序&C是函数式语言&必须有且只能有一个名为main的主函数&C程序的执行总是从main函数开始,在main中结束&函数不能嵌套定义,可以嵌套调用5.1 函数的声明、定义与调用 5.1.1 5.1.1 函数的声明与定义函数的声明与定义5.1.2 5.1.2 函数调用函数调用5.1.3 5.1.3 函数参数传递函数参数传递5.1.4 5.1.4 主函数中的参数主函数中的参数5.1.1函数的声明与定义函数的声明与定义1.1.函
4、数函数声明的意义:声明的意义:函数声明是对所用到的函数的特征进行必要的说明。函数声明是对所用到的函数的特征进行必要的说明。编译系统以函数声明中给出的信息为依据,对调用表编译系统以函数声明中给出的信息为依据,对调用表达式进行测试达式进行测试。2.2.函数函数声明格式声明格式:类型类型标识符标识符 函数名函数名(标识符标识符 形参,标识符形参,标识符 形形参参 );例:例:float area(float float area(float r);r);float area (float r)float s=0;s=3.14*r*r;return s;函数体内容函数体内容3.函数定义函数定义去掉去掉
5、函数声明结尾函数声明结尾分分号,加函数号,加函数体。体。4.函数函数定义例子定义例子5.1.2 函数调用函数调用函数名函数名(实参实参表表列列)例例:printf(“c程序设计程序设计n”);2.使用函数表达式:使用函数表达式:例:例:y=sin(x)+log(fabs(pow(x,3);3.函数作实参函数作实参 例:例:y=log(fabs(pow(x,3);1.使用函数调用语句使用函数调用语句要返回值要返回值不要返回值不要返回值带参数带参数不带参数不带参数虚实结合的次序:从右虚实结合的次序:从右向左逐个结合向左逐个结合【例例】int x=6;fun(x,x+=2);【例5-1】有返回值的函
6、数调用方法。在主函数中,由键盘上输入圆半径r的值,调用子函数Area(),计算出圆面积,在主函数中输出圆面积。#include#define PI 3.14float Area(float r)/函数的定义 float s=0;s=PI*r*r;return s;void main()float r,s;printf(“请输入圆的半径r:”);scanf(“%f”,&r);s=area(r);/函数调用 printf(s=%0.2fn,s);【例5-2】无返回值的函数调用方法。在子函数maxTwo()中输出两个数中的较大者。#include void maxTwo(int x,int y)in
7、t max=xy?x:y;printf(max=%d,max);void main()int m=10;int n=5;maxTwo(m,n);【例5-3】无参函数 调用。下面是使用无参函数的打印消息程序。#include printstar()printf(*n);printmess()printf(中华民族复兴百年强国之梦 n);main()printstar();printmess;printstar();5.1.3函数参数传递函数参数传递 1.传值调用传值调用 【例例5-4】函数的传值调用,请分析数据交换子函数Swap()被调用前后,主函数内的两个整型变量m、n的结果。#include
8、 void Swap(int ia,int ib)int ic ic=ia;ia=ib;ib=ic;void main()int m=10;int n=5;printf(调用Swap()函数前:m=%d,n=%dn,m,n);swap(m,n);printf(调用Swap()函数后:m=%d,n=%dn,m,n);2.传址调用传址调用【例5-5】利用传址调用,编写一个生成、输出斐波那契数列前N(例如N=20)项,并统计出前n(n=N,例如n=15)项和的程序。#include#include#define N 20CreateFibonacci(int iF)int i;iF0=iF1=1;f
9、or(i=2;iN;i+)iFi=iFi-2+iFi-1;void PrintFibonacci(int iF)int i;puts(斐波那契数列);for(i=0;iN;i+)printf(%dt,iFi);if(i+1)%10=0)printf(n);printf(n);int Sum(int iF,int n);void main()int i,FibonacciN,m,n;/生成斐波那契数列CreateFibonacci(Fibonacci);/输出斐波那契数列PrintFibonacci(Fibonacci);/求数列前n项的和printf(请输入要求和的项数n(n%d):,N);s
10、canf(%d,&n);m=Sum(Fibonacci,n);printf(n 斐波那契数列前%d项的和:%4dn,n,m);/定义Sum函数int Sum(int iF,int n)int i,iTotal=0;for(i=0;in;i+)iTotal+=iFi;return(iTotal);数组名可作函数数组名可作函数参数参数实参实参和形参都应用数组名和形参都应用数组名.2109score562312.88array例:例:求学生的平均成绩求学生的平均成绩#include void main()float average(float array10);float score10,aver;
11、int i;printf(Input 10 scores:n);for(i=0;i10;i+)scanf(%f,&scorei);printf(“n”);aver=average(score);printf(Average is:%5.2f,aver);float average(float array10)int i;float aver,sum=array0;for(i=1;i10;i+)sum=sum+arrayi;aver=sum/10;return(aver);几点说明几点说明:v1)形参数组和实参数组的类型必须一致v(2)当实参是一维数组时,形参数组的长度可以缺省,但一对方括号不得
12、缺省。当实参是二维数组时,形参数组的行数可缺省,但列数不得缺省。v(3)形参和实参数组的长度可以不相同,因为在调用时,只传送首地址而不检查形参数组的长度。当形参数组的长度与实参数组不一致时,虽不至于出现语法错误(编译能通过),但程序执行结果将与实际不符,这是应予以注意的。*5.1.4 主函数主函数main()中的参数中的参数(不讲)不讲)在操作系统环境下的命令格式在操作系统环境下的命令格式:命令命令 参数参数1 1 参数参数2 2 此格式也称为命令行此格式也称为命令行。例:例:program str1 str2 str3 str4 str5 program str1 str2 str3 str
13、4 str5 其中其中programprogram为为可执行可执行文件名文件名;其后各跟其后各跟5 5个参数。个参数。main(main(intint argc,charargc,char *argvargv)intint argcargc:记录命令行中命令与参数的个数,记录命令行中命令与参数的个数,;char char*argvargv:各各参数的值。参数的值。【例例5-6】:设程序名为设程序名为5-6.exe,输出命令行参数值。输出命令行参数值。#include main(int argc,char*argv)printf(参数个数:参数个数:%dn,argc);printf(第一个参数:
14、第一个参数:%sn,argv0);printf(第二个参数:第二个参数:%sn,argv1);在命令行输入如下命令:在命令行输入如下命令:5-6.exe 11 22 输出结果:参数个数:输出结果:参数个数:3 第一个参数:第一个参数:11 第二个参数:第二个参数:22 5.2.15.2.1函数函数的嵌套调用的嵌套调用 不不允许嵌套定义允许嵌套定义,函数,函数间平行的间平行的、独立。独立。C C中的函数中的函数:允许允许嵌套嵌套调用调用。main()调用函数调用函数a结束结束a函数函数b函数函数调用函数调用函数b5.2 函数的嵌套与递归调用输入:输入:3 4输出:输出:The result is
15、:25【例例5-75-7】输入两个整数,求平方和输入两个整数,求平方和#include int fun1(int x,int y);void main(void)int a,b;scanf(“%d%d”,&a,&b);printf(“The result is:%dn”,fun1(a,b);int fun1(int x,int y)int fun2(int m);return(fun2(x)+fun2(y);int fun2(int m)return(m*m);5.2.2 5.2.2 函数函数的递归调用的递归调用递归:递归:一个函数在它的函数一个函数在它的函数体内体内出现出现调用调用它它自身自
16、身的语句的语句。f()调调fint f(int x)int y;z=f(y);.return(2*z);递归递归:在函数调用自身时在函数调用自身时,要要给出结束递归的条件给出结束递归的条件。l先递推再回归先递推再回归l如:如:n n!,!,5 5!=5!=5 4!4!4!=4 4!=4 3!3!3!=3 3!=3 2!2!2!=2 2!=2 1!1!1!=11!=1 0!=1 0!=1 1 (n=0,1)n!=n*(n-1)!(n1)#include long factorial(int n)long ip;if(n=0|n=1)ip=1;else ip=factorial(n-1)*n;re
17、turn(ip);void main()int n;long m;printf(“请输入一个整数请输入一个整数:);scanf(%d,&n);m=factorial(n);printf(%d!=%15d,n,m);运行:运行:请输入一个整数:请输入一个整数:1010!=3628800【例例5-85-8】用递归方法求用递归方法求n!n!age(5)age(4)age(3)age(2)age(1)=2+age(4)=2+age(3)=2+age(2)=2+age(1)=10=18 =16 =14 =12【例例5-95-9】:有有5 5个人,第个人,第5 5个人比第个人比第4 4个人大个人大2 2岁
18、,第岁,第4 4个人比第个人比第3 3个人大个人大2 2岁岁,第第2 2个人比第个人比第1 1个人大个人大2 2岁,第岁,第1 1个人个人1010岁,问第岁,问第5 5个人多大?个人多大?10 n=1数学模型:数学模型:age(n)=age(n-1)+2 n1运行结果:运行结果:18age(int n)int c;if(n=1)c=10;else c=2+age(n-1);return(c);#include void main()printf(“%d n”,age(5);5.3 内部函数和外部函数内部函数和外部函数 根据函数能否被其它源文件调用,将函数分为内部函根据函数能否被其它源文件调用,
19、将函数分为内部函数和外部函数。数和外部函数。5.3.1 5.3.1 内部函数内部函数静态函数静态函数v只能被本文件中其它函数所调用只能被本文件中其它函数所调用v定义形式定义形式:static static 类型标识符类型标识符 函数名(函数名(形参表形参表)如:如:static static intint fun(fun(intint a,a,intint b)b)v内部函数作用域:内部函数作用域:仅限于定义它的所在文件。仅限于定义它的所在文件。5.3.2 5.3.2 外部外部函数函数v能被其它文件中的函数所调用能被其它文件中的函数所调用v定义形式:定义形式:extern extern 类型标
20、识符类型标识符 函数名函数名(形参表形参表)如:如:extern extern intint fun(fun(intint a,a,intint b)b)v省略省略externextern,隐含为外部函数,隐含为外部函数v调用此函数的文件中也要用调用此函数的文件中也要用externextern声声明所用函明所用函数是外部数是外部函数函数【例例5-105-10】简单简单选择排序算法编写程序选择排序算法编写程序 分析分析:该该问题可以用问题可以用2 2个函数解决个函数解决。主。主函数函数main()main(),排序排序函数函数sort()sort(),将各函数放入将各函数放入2 2个文件,用个文
21、件,用externextern声明实现各文件中函数的调用。声明实现各文件中函数的调用。f2.cvoid sort(int a,int n)int i,j,k,c;for(i=0;in-1;i+)k=i;for(j=i+1;jn;j+)if(ajak)k=j;if(k!=i)c=ai;ai=ak;ak=c;f1.cmain()extern void sort(int a,int n);int a10,i;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i(Y)?(X):(Y)5.4 5.4 带参数的宏定义带参数的宏定义28【例例5-115-11】:
22、带参数的宏的用法。求两个数中的较大者。:带参数的宏的用法。求两个数中的较大者。#include#define MAX(a,b)(ab)?a:bmain()float x,y,max;printf(请输入两个数:);scanf(%f%f,&x,&y);max=MAX(x,y);printf(max=%0.2fn,max);2930#include#define L 5#define F(x)(4*x*x*x-6*x*x*L+L*L*L)/挠度曲线的导函数#define F1(x)(12*x*x-12*x*L)/导函数的导函数void main()double x1,x2,eps=1e-6;x1=
23、2;x2=x1-F(x1)/F1(x1);/由x1用宏调用计算出x2while(fabs(x2-x1)eps)x1=x2;x2=x1-F(x1)/F1(x1);x2=(x1+x2)/2;printf(最大挠度发生点在梁的:%0.2lf m处n,x2);5.5 库函数及预处理命令#include1.1.由编译系统提供的一系列函数,以库形式存放在系统中,由编译系统提供的一系列函数,以库形式存放在系统中,不是不是C C语言文本的组成部分。语言文本的组成部分。2.2.调用形式调用形式:函数名(函数名(参数表参数表)3.3.注意在调用注意在调用C C语言库函数时,需要使用编译预处理命令语言库函数时,需要
24、使用编译预处理命令#include#include ,使相应的头文件包含到用户源,使相应的头文件包含到用户源程序中。程序中。32头文件名函数类型头文件名函数类型stdio.h标准输入输出库函数time.h时间库函数(大多是用于UNIX系统)string.h字符串处理库函数stdlib.h内存分配、随机数发生器、类型转换库函数ctype.h字符判断库函数conio.h文本窗口库函数(仅用于IBM PC及其兼容机)dir.h文件目录操作库函数dos.hC程序与操作系统接口库函数math.h数学运算库函数graphics.h图形库函数(仅适用于Turbo C系统)表表5-15-1常用头文件所包含的库
25、函数类型常用头文件所包含的库函数类型5.6 函数综合应用举例【5-135-13】编写一个万年历程序,提示用户输入年份和月编写一个万年历程序,提示用户输入年份和月份信息,程序份信息,程序将输出将输出该年该月的日历该年该月的日历。例如。例如程序运行程序运行时输入年份:时输入年份:20132013年,月份年,月份:3:3月,现实的结果月,现实的结果如如图图5-35-3所示。所示。分析:分析:日历表日历表的的主要打印两部分:打印日历表标题部分和主要打印两部分:打印日历表标题部分和日历的主体部分。日历的主体部分。打印主体部分,打印主体部分,应应知道知道:(1 1)要打印月的第一天是星期几?)要打印月的第
26、一天是星期几?以某个已知天的参考,用以下公式计算:以某个已知天的参考,用以下公式计算:如:如:已知已知19001900年年1 1月月1 1日为星期一。日为星期一。则:则:要打印月的第一天的星期要打印月的第一天的星期 =(要打印月的第一天(要打印月的第一天离离19001900年年1 1月月1 1日的总天数日的总天数 +1+1)%7%7(2)要打印的月的总天数?)要打印的月的总天数?A.1、3、5、7、8、10、12月份月份:31天;天;B.4、6、9、11月月:30天;天;C.2月月:闰年为闰年为28天,否则为天,否则为29天。天。D.闰年的判断规则闰年的判断规则:只要满足以下两个条件之一,就是
27、只要满足以下两个条件之一,就是闰年。闰年。条件条件1:能被:能被4整除,但不能被整除,但不能被100整除整除 条件条件2:能被:能被400整除整除日历程序函数调用关系图 函数说明:函数说明:main()/程序入口主函数程序入口主函数int readYear()/读取用户输入的年份数据读取用户输入的年份数据int readMonth()/读取用户输入的月份数据读取用户输入的月份数据 void printMonth(int year,int month)/打印打印year年年month月的日历表月的日历表void printMonthTitle(int year,int month)/打印日历标题
28、打印日历标题 void printMonthBody(int year,int month)/打印日历主体打印日历主体/获取获取year年年month月的第一天的星期数月的第一天的星期数 int getStartDay(int year,int month)/获取从获取从1900年年1月月1日日(星期一星期一)到到year年年month月月1日的相隔总天数日的相隔总天数 int getTotalDays(int year,int month)/获取获取year年年month月的总天数月的总天数 int getMonthDays(int year,int month)/判断判断year年是否为闰
29、年(如果为闰年,则返回年是否为闰年(如果为闰年,则返回1,否则返回,否则返回0)int isLeapYear(int year)#include int readYear()/输入年份函数输入年份函数 int Year;printf(请输入年份:请输入年份:);scanf(%d,&Year);return Year;int readMonth()/输入月份函数输入月份函数 int Month;printf(请输入月份:请输入月份:);scanf(%d,&Month);return Month;int isLeapYear(int Year)/判断闰判断闰年函数年函数 if(Year%4)=0&
30、(Year%100!=0)|(Year%400=0)return 1;else return 0;int getMonthDays(int Year,int Month)/获得所在年月的天数函数获得所在年月的天数函数 int Days;switch(Month)case 1:case 3:case 5:case 7:case 8:case 10:case 12:Days=31;break;case 4:case 6:case 9:case 11:Days=30;break;case 2:if(isLeapYear(Year)Days=29;else Days=28;break;return D
31、ays;int getTotalDays(int Year,int Month)/1900年年1月月1日到当前年月日到当前年月的间隔天数的间隔天数 int Days=0,i=0;for(i=1900;iYear;i+)if(isLeapYear(i)Days=Days+366;else Days=Days+365;/累计月份天数计算总天数累计月份天数计算总天数 for(i=1;iMonth;i+)Days=Days+getMonthDays(Year,i);return Days;int getStartDay(int Year,int Month)/获得第一天的星期数获得第一天的星期数 in
32、t startDay=(1+getTotalDays(Year,Month)%7;return startDay;void printMonthBody(int Year,int Month)/打印日历内容打印日历内容 int i;/循环变量循环变量 int count;/开始星期数开始星期数 int Days;/当月天数当月天数 count=getStartDay(Year,Month);Days=getMonthDays(Year,Month);/打印空格打印空格 for(i=0;icount;i+)printf();/打印数据打印数据 for(i=1;i=Days;i+)printf(%
33、3d,i);count+;if(count%7=0)printf(n);puts(n-n);void printMonthTitle(int Year,int Month)/打印日历标题打印日历标题 printf(tt%d年年%d月月n,Year,Month);puts(-n);puts(日日 一一 二二 三三 四四 五五 六六n);void printMonth(int Year,int Month)/打印日历打印日历 printMonthTitle(Year,Month);/打印日历标题打印日历标题 printMonthBody(Year,Month);/打印日历主体打印日历主体main(
34、)/输入年份输入年份 int Year=readYear();/输入月份输入月份 int Month=readMonth();/打印日历打印日历 printMonth(Year,Month);【5-145-14】编程求解】编程求解10100001010000以内的所有超级素数以内的所有超级素数。所谓所谓超级素数指如果一个素数组成它超级素数指如果一个素数组成它的的:所有所有数码数码的和的和:SumSum、所有所有数码的积:数码的积:ProductProduct、所有所有数码的平方和:数码的平方和:SumSquareSumSquare也也都是素数的数都是素数的数。算法分析:算法分析:(1 1)只有
35、奇数才可能是素数,)只有奇数才可能是素数,因此判断因此判断应从应从i=11i=11循环到循环到1000010000,按步长为,按步长为2 2进行。进行。(2 2)调用求素数函数)调用求素数函数Prime(i)Prime(i)判断判断i i是否为素数。如是是否为素数。如是,再做判断它是否为超级素数的事情,否则进入下一轮,再做判断它是否为超级素数的事情,否则进入下一轮循环,判断一个奇数是否为素数。循环,判断一个奇数是否为素数。(3 3)当某奇数)当某奇数i i已被确定为素数时,下面的工作是:已被确定为素数时,下面的工作是:A A、将将m m(=i=i)分解分解成组成它的各位成组成它的各位数码数码,
36、并对数码进行求和、积平方和三种,并对数码进行求和、积平方和三种运算。运算。方法:方法:循环循环对对m m进行进行m%10m%10、M/=10M/=10运算运算,将所得的数码将所得的数码求和求和、求积、求平方、求积、求平方和的运算,直到和的运算,直到m m为为0 0时分解结束。时分解结束。B B、调用调用Prime()Prime()函数,判断数码和是否为素数,是继续函数,判断数码和是否为素数,是继续第第C C步步,否则跳到,否则跳到i i循循环的下一轮,判断另一个奇数是否为素数。环的下一轮,判断另一个奇数是否为素数。C C、调用调用Prime()Prime()函数,判断数码积是否为素数,是继续函
37、数,判断数码积是否为素数,是继续第第D D步步,否则跳到,否则跳到i i循循环的下一轮,判断另一个奇数是否为素数。环的下一轮,判断另一个奇数是否为素数。D D、调用调用Prime()Prime()函数,判断数码平方和是否为素数,是继续第函数,判断数码平方和是否为素数,是继续第5 5步,否则跳到步,否则跳到i i循环的下一轮,判断另一个奇数是否为素数。循环的下一轮,判断另一个奇数是否为素数。E E、经过经过2 2、3 3、4 4步,证明步,证明i i满足了超级素数的条件,输出,并让计数器满足了超级素数的条件,输出,并让计数器+1.+1.源程序如下:源程序如下:#include#include i
38、nt Prime();void main()int i,digit,m,Flag;int Sum,Product,SumSquare;int Count=0;puts(10 到到 10000 之间的全部超级之间的全部超级素数:素数:);/循环求循环求10,10000之间的所有超级之间的所有超级素数素数for(i=11;i0);Flag=Prime(Sum);if(!Flag)continue;Flag=Prime(Product);if(!Flag)continue;Flag=Prime(SumSquare);If(Flag)printf(%d ,i);/条件全部满足,条件全部满足,i一定是超
39、级素数,予以输出一定是超级素数,予以输出 Count+;printf(n总共总共%d个超级素数个超级素数n,Count);int Prime(int m)int n,j;if(m2)return 0;/0、1不是素数不是素数n=sqrt(m);for(j=2;j=n;j+)if(m%j=0)/m不能被不能被j整除,一定不是素数整除,一定不是素数 return 0;return 1;/循环正常结束,循环正常结束,m一定是素数一定是素数运行运行【例【例5-155-15】制作一张有】制作一张有1010个学生成绩单,成绩由随机函个学生成绩单,成绩由随机函数生成,运行结果如图数生成,运行结果如图5-65
40、-6所示。所示。算法分析算法分析:(1 1)从学生成绩单输出结果可看出,成绩数组)从学生成绩单输出结果可看出,成绩数组ScoreScore应是一个应是一个M M*N N的的浮点数矩阵浮点数矩阵(M=11,N=5)(M=11,N=5),成绩表的第,成绩表的第1 1列与成绩数组列与成绩数组ScoreMNScoreMN本本身无关,是一个附加列,目的是输出学生的序号和身无关,是一个附加列,目的是输出学生的序号和“总平均总平均”;同;同样,表头也不是样,表头也不是ScoreMNScoreMN的内容。的内容。(2 2)表头和表线可事先定义在一个字符型二维数组)表头和表线可事先定义在一个字符型二维数组s68
41、0s680中。其中。其中所涉及的各中图形字符,全部取自于汉字中所涉及的各中图形字符,全部取自于汉字GB2312-80GB2312-80中第中第9 9区的制区的制表符。表符。(3 3)ScoreMNScoreMN前前M-1M-1行、行、N-1N-1列的各元素值,应由成绩生成函数列的各元素值,应由成绩生成函数CreateScoreCreateScore(float ScoreN)(float ScoreN)生成。其中第生成。其中第M-1M-1行、行、N-1N-1列前面的列前面的各元素值,通过随机数函数生成,并进行适当的技术处理。第各元素值,通过随机数函数生成,并进行适当的技术处理。第M-1M-1行
42、行、N-1N-1列的个元素值,是前面各行、各列元素之求平均的结果列的个元素值,是前面各行、各列元素之求平均的结果。(4 4)表头的打印由函数)表头的打印由函数PrintStringPrintString(char(char strstr80)80)完成。它可完成。它可通过循环的方式将通过循环的方式将s680s680中的中的s0s0、s1s1、s2s2、s3s3打印出来打印出来,组成表头。,组成表头。(5 5)成绩单由函数)成绩单由函数PrintRecordPrintRecord(float ScoreN,(float ScoreN,strstr80)80)实实现,要完成如下任务:现,要完成如下
43、任务:外外循环(循环(i=0M-2i=0M-2)开始,打印)开始,打印“”“”和学生的学号(最后一行应和学生的学号(最后一行应打印打印“总平均总平均”););内内循环开始,循环打印循环开始,循环打印“”“”和和ScoreScore数组的元素;数组的元素;内内循环结束,打印循环结束,打印“”“”并换行;并换行;打印打印字符串字符串strstr44;对于对于把最后一行(把最后一行(i=M-1i=M-1),应先打印),应先打印“”“”和和“总平均总平均”,然,然后再按后再按2 2、3 3打印打印ScoreScore数组第数组第M-1M-1行的各元素,最后应打印行的各元素,最后应打印strstr55,
44、从而结束表格打印从而结束表格打印。(6 6)总平均是按列进行平均,由子函数)总平均是按列进行平均,由子函数AverageAverage(float float ScoreNScoreN)来实现。)来实现。(7 7)在主程序中通过对四个子函数的调用完成成绩表的制作。)在主程序中通过对四个子函数的调用完成成绩表的制作。源程序:源程序:#include#include#define M 11#define N 5void CreateScore();void PrintString();void PrintRecord();void Average();void main()float ScoreM
45、N=0;int i;/下面表格的字符全部取自于汉字图形字符下面表格的字符全部取自于汉字图形字符集集GB2312-80中的制表符中的制表符char s80=学生成绩统计表学生成绩统计表,学学 号号 高数高数 物理物理 C语言语言 电工电工 平均平均,;CreateScore(Score);Average(Score);PrintString(s);PrintRecord(Score,s);void CreateScore(float ScoreN)int i,j;float temp,Sum;for(i=0;iM-1;i+)Sum=0;/随机生成随机生成学生各门功课的成绩学生各门功课的成绩 fo
46、r(j=0;jN-1;j+)temp=rand()%101;if(temp25)temp+=25;temp=sqrt(temp)*10;Scoreij=temp;Sum+=temp;ScoreiN-1=Sum/(N-1);void PrintString(char str80)/打印表头打印表头 int i;for(i=0;i4;i+)printf(%sn,stri);void PrintRecord(float ScoreN,char str80)/打印成绩单打印成绩单 int i,j;printf(%sn,str4);for(i=0;iM;i+)if(iM-1)printf(%4d,i+1);elseprintf(总平均总平均);for(j=0;jN;j+)printf(%4.1f,Scoreij);printf(n);if(iM-1)printf(%sn,str4);printf(%sn,str5);void Average(float xN)/求每门功课求每门功课全体学生的平均分全体学生的平均分int i,j;float sum;for(i=0;iN;i+)sum=0;for(j=0;jM-1;j+)sum+=xji;xji=sum/(M-1);(本章结束,按按钮返回)(本章结束,按按钮返回)