C语言第三次大作业_第1页
C语言第三次大作业_第2页
C语言第三次大作业_第3页
C语言第三次大作业_第4页
C语言第三次大作业_第5页
已阅读5页,还剩29页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言第三次大作业班级:机电*姓名:*学号:*题目一:利用数组编写一个简单的成绩管理系统,要求有效依据至少150条,利用程序设计模块化思想,自定义函数不少于5个。其他要求:1、班级的人数由用户键盘输入;2、录入学生学号和考试成绩3、数据分析功能包括计算课程总分和平均分、按成绩由高到低排出成绩表、按学号由小到大排出成绩表、可按学号查询学生成绩及排名、按优秀(90100),良好(8089),中等(7079),及格(6069),不及格(<60)5个类别统计成绩并计算百分比和输出每个学生的学号、成绩及课程总分和平均分。1、题意及算法分析根据题目要求,结合程序设计模块化思想,可自定义79个函数,分

2、别实现相应的功能。根据题目要求可定义学号数组为整形数组,平均分、成绩数组为float类型;定义宏常量N,使得数组足够大;成绩和学号的排序可采用交换法、选择法、插入排序、冒泡法、快速排序法等,本题采用交换法排序,在采用交换法排序的时候可以通过定义一个标志变量(中间变量)实现;通过学号查找成绩可通过线性查找(顺序查找)或折半查找,本题采用的是顺序查找,采用顺序查找可以用for循环语句实现,查找次数最多为总人数n。统计等级时,利用整数除法(区别于实数除法),结合switch语句和计数控制循环语句即可得到不同等级所占百分比。菜单功能选择是可使用switch-case条件结构。要注意的是数组的下标从0开

3、始;只能逐个引用数组元素,不能一次引用整个数组;数组做函数形式参数时,数组的大小可以不出现在数组名后面的方括号内;被调用函数的实际参数用数组名或数组定义式。2、NS流程图输入学生人数录入各个学生的学号和成绩无限循环是否常量1是否按ESC键退出相等退出循环常量2不等相等计算课程总分和平均分不等相等按成绩由高到低排出成绩表不等常量4常量3相等按学号由小到大排出成绩表不等常量5相等按学号查询学生成绩及其成绩不等常量6相等统计各等级所占的百分比不等其他常量相等输出每个学生的学号成绩及课程的总分和平均分不等输出“对不起,没有该功能选项!”重新选择功能传统流程图:注:功能1: 计算课程总分和平均分功能2:

4、 按成绩由高到低排出名次表功能3:按学号由小到大排出成绩表功能4:按学号查询学生排名及其成绩功能5:统计各等级所占的百分比功能6:输出每个学生的学号、成绩,课程总分和平均分功能7:输出“对不起,没有该功能选项!”Y常量1N输入是否为数字Y结束N录入各个学生的学号和成绩输入学生总人数break功能1break功能2break功能3break功能4break功能5break功能6break功能7default常量6常量5常量4常量3常量2开始是否按ESC键退出3、调试及改错1、缺少取地址运算符“&”写好程序后,解决ERROR后会情不自禁的执行程序,一执行便弹出如下对话框,回过头看程序,发现

5、int read(long number,float score)函数中“printf("请输入学生总人数:"); ret=scanf("%d",n);”的语句中出现一个明显的低级错误,缺少取地址运算符“&”。2、交换法排序逻辑错误解决了上述错误后,程序运行时执行功能2,出现如下错误,并没有达到预期交换成绩的目的,但是学号却排序正确,可以初步确定错误出现在void sort(long number,float score, int n)函数中。检查发现标志变量temp为起到作用,交换法语句中出现逻辑错误。错误的程序语句及修改如下:void sor

6、t(long number,float score,int n)int i,j;float temp;long m;for(i=1;i<n;i+)for(j=0;j<n-i;j+)if(scorej<scorej+1)scorej=temp; / 应改为“temp=scorej;”m=numberj;scorej=scorej+1; numberj=numberj+1;scorej+1=temp; numberj+1=m;printf("n");for(i=0;i<n;i+)printf("成绩第%d名成绩:%ldt%.1fn",

7、i+1,numberi,scorei);3、数据类型错误解决了以上问题,再次编译组建执行时,统计各等级所占百分比出现失真。各成绩等级均为0.00%。如下图所示:一开始并未发现问题,step into void analysis(float score,int n)函数调试,输入3位学生成绩分别是98,93和67,调试时查看数据,如下图:(100*a)/10的值并非为0,但是输出结果却是0.00%。错误的程序语句及修改:void analysis(float score,int n)int a=0,b=0,c=0,d=0,e=0,i;for(i=0;i<n;i+)switch(int)sc

8、orei/10)case 10:case 9:a=a+1;break;case 8:b=b+1;break;case 7:c=c+1;break;case 6:d=d+1;break;default:e=e+1;printf("n");printf("优秀(90100)的人数为:%4dn",a); printf("良好(80 89)的人数为:%4dn",b); printf("中等(70 79)的人数为:%4dn",c); printf("及格(60 69)的人数为: %4dn",d);prin

9、tf("不及格(059)的人数为: %4dn",e); printf("优秀率: %.2f%n",float(100*a)/n); /红色为修改后添加语句printf("良好率: %.2f%n",float(100*b)/n); /因为ae,n已被定义为intprintf("中等率: %.2f%n",float(100*c)/n); /而输出却是float类型 printf("及格率: %.2f%n",float(100*d)/n); /因此必须把(100*a)/aprintf("不及

10、格率:%.2f%n",float(100*e)/n);/转化为强制转化为float型4、源程序#include <stdio.h>#include <conio.h>#include <windows.h>#define N 100void screen(char c);int read(long number,float score);void total_average(float score,int n);void sort(long number,float score,int n);void sortnumber(long number,

11、float score,int n);void search(long number,float score,int n);void analysis(float score,int n);void listrecord(long number,float score,int n);void main(void)int n=0;char choose;char ch="简单的学生成绩管理系统by施芳辉"long numberN;float scoreN;screen(ch);n=read(number,score); /数组名做函数实参调用函数read()while(1)p

12、rintf("n");printf("1、计算课程总分和平均分n");printf("2、按成绩由高到低排出名次表n");printf("3、按学号由小到大排出成绩表n");printf("4、按学号查询学生排名及其成绩n");printf("5、统计各等级所占的百分比n");printf("6、输出每个学生的学号、成绩,课程总分和平均分n");printf("请选择分析功能(按ESC退出):");choose=getche();if(

13、choose=27)break;elseswitch(choose)case 49:printf("n");total_average(score,n); /调用计算课程总分和平均分的函数break;case 50:printf("n");sort(number,score,n);/调用成绩排序函数break;case 51:printf("n");sortnumber(number,score,n);/调用学号排序函数break;case 52:printf("n");search(number,score,n)

14、; /调用查询函数research()break;case 53:printf("n");analysis(score,n); /调用统计等级函数analysis()break;case 54:printf("n");listrecord(number,score,n);break;default:printf("n");printf("对不起,没有该功能选项!");break;void delay(void)int a;for(a=0;a<2000;a+);void gotoxy(int x,int y)C

15、OORD c=x,y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);void screen(char c)int i;gotoxy(20,1);for(i=0;i<5;i+)printf("37");Sleep(200);delay();printf("%s",c); /输出字符串数组ch中的内容for(i=0;i<5;i+)printf("37");Sleep(200);delay();putchar('n');int read(l

16、ong number,float score) /录入学生成绩,返回学生人数供后续函/数使用int n,i,ret;printf("n");printf("请输入学生总人数:");ret=scanf("%d",&n);/记录scanf函数的返回值while(ret!=1) /此处输入数据个数或格式是否错误while(getchar()!='n');/清除输入缓冲区中错误数据printf("请输入学生总人数:");ret=scanf("%d",&n);/记录scan

17、f函数的返回值for(i=0;i<n;i+)printf("请输入第%d位学号和成绩:如(0000000,90.0):",i+1); ret=scanf("%ld%*c%f",&numberi,&scorei); / *为忽略输入修/饰符,此处%*c使得输入学号与成绩之间可用任意一个字符隔开while(ret!=2) /此处while语句与上述作用一样while(getchar()!='n');printf("请输入第%d位学号和成绩:如(0000000,90.0):",i+1);ret=scan

18、f("%ld%*c%f",&numberi,&scorei);return n;void total_average(float score,int n)int i;float sum=0;for(i=0;i<n;i+) /总分计数循环语句 sum=sum+scorei;printf("n");printf("该课程的总分为:%.2fn",sum); / “.2” 对于float类型,限/定其小数点位数为2位printf("课程的平均分为:%.2fn",sum/n);void sort(lon

19、g number,float score,int n)int i,j;float temp; /定义一个标志变量,用于排序long m;for(i=1;i<n;i+) for(j=0;j<n-i;j+) /此段程序if(scorej<scorej+1)/用于成绩/的排序,temp=scorej;/并交换m=numberj;/相应的scorej=scorej+1;/学号 numberj=numberj+1;scorej+1=temp; numberj+1=m; printf("n");for(i=0;i<n;i+)printf("成绩第%d名

20、成绩:%ldt%.1fn",i+1,numberi,scorei);void sortnumber(long number,float score,int n) /此函数与上述sort()/函数类似,关键是排序int i,j;float temp;long m;for(i=1;i<n;i+)for(j=0;j<n-i;j+)if(numberj>numberj+1)m=numberj;temp=scorej;numberj=numberj+1;scorej=scorej+1;numberj+1=m;scorej+1=temp;printf("n"

21、);for(i=0;i<n;i+)printf("学号由小到大排序:%ldt%.1fn",numberi,scorei);void search(long number,float score,int n)int i;long sort;printf("请输入要查询的学生学号:"); scanf("%ld",&sort);printf("n");for(i=0;i<n;i+) /利用for循环语句,实现顺序查找 if(numberi=sort) printf("查询学生的学号%ld,成

22、绩为%.1fn",sort,scorei); void analysis(float score,int n)int a=0,b=0,c=0,d=0,e=0,i;for(i=0;i<n;i+)switch(int)scorei/10) /数据类型的强制转换,因为score数组/的数据类型是float,而这里算等级利用整数。case 10:case 9:a=a+1;break;case 8:b=b+1;break;case 7:c=c+1;break;case 6:d=d+1;break;default:e=e+1;printf("n");printf(&qu

23、ot;优秀(90100)的人数为:%4dn",a); printf("良好(80 89 )的人数为:%4dn",b); printf("中等(70 79 )的人数为:%4dn",c); printf("及格(60 69 )的人数为: %4dn",d);printf("不及格(059)的人数为: %4dn",e); printf("优秀率: %.2f%n",float(100*a)/n);/同样的,a,n均定义为int/类型,要得到精确2位小数点,要把((100*a)/n)强制转换为fl

24、oat类型。printf("良好率: %.2f%n",float(100*b)/n);printf("中等率: %.2f%n",float(100*c)/n); printf("及格率: %.2f%n",float(100*d)/n); printf("不及格率:%.2f%n",float(100*e)/n);void listrecord(long number,float score,int n)int i;printf("n");for(i=0;i<n;i+)printf("

25、;学生学号为%ld的成绩是:%.1fn",numberi,scorei);total_average(score,n);5、心得体会要写好一个程序并不容易,就像这么一个并不是特别复杂的程序,刚写好时错误百出,就连最低级的错误如缺少“;”,取地址运算符“&”,数据的定义(特别是数据类型),数据的初始化都会出错,原因只有一个:不细心、少实践、少留心!程序写多了,改多了,自然在写的时候就会多留一份心,自然会在写到容易出错的地方提醒自己。本次特别加强了程序流程图的学习。题目二:基于V2写一个键控的简单的菜单功能选择程序,可以计时、可以定时、可以摇号(摇号范围自定)。定时、计数要求使用

26、外部晶振(约12M),结合定时器/计数器原理,精确到0.01秒,最长计时99.99秒。显示格式形如“00.00”。同时,秒表可以记录多个时间点,并在数码管轮流显示;定时器定时时间可通过按键调整,定时范围自定。1、 算法及题意分析菜单可以利用K2键选择功能“1”“2”或“3”,键控秒表可以使用K2键开始,每按K3键记录一次,再按K2键把记录的成绩依次在数码管上显示。0.01秒精确度,可使用定时器T0定时0.01秒(初始值TH0=(65535-10000)/256,TL0=(65536-10000)%256),可采用中断法或查询法,每定时完成一次数码管显示一次。定时器可以设置K2键没按一次,定时时

27、间增加相应的量(10S),K3键暂停,再按K2键继续。摇号可利用Rand()函数,K2键按下时获得摇号数字,K3键重新摇号。每个功能在初始态通过按K3键返回功能选择菜单。2、 源程序#include <stc12C5410ad.h>#include <intrins.h>#include <stdlib.h>#define N 40 /秒表计时器最多可记录40个数据void dis_init(void);void display(unsigned int qian,unsigned int bai,unsigned int shi,unsigned int

28、ge);void second(void); /秒表函数的说明void jsq(void);/定时器函数的说明void random(void);/摇号函数的说明sbit k1=P26;sbit k2=P37;sbit k3=P27;sbit k4=P21;sbit dp=P20; /数码管小数点位定义sbit key3=P24; /按键的位定义sbit key2=P25;unsigned char code discode=0x84,0x9F,0xd0,0x91,0x8B,0xA1,0xA0,0x97,0x80,0x81;/数码管字型码,09unsigned int temp2=0,temp

29、3=0,qian=0,bai=0,shi=0,ge=0;void delay(void) /10ms,误差0us unsigned char a,b,c; for(c=1;c>0;c-) for(b=38;b>0;b-) for(a=130;a>0;a-);void delay2(void) unsigned char a,b,c; for(c=243;c>0;c-) for(b=50;b>0;b-) for(a=15;a>0;a-);void delay2s(void) /误差 0us unsigned char a,b,c; for(c=127;c>

30、;0;c-) for(b=235;b>0;b-) for(a=32;a>0;a-); _nop_(); /if Keil,require use intrins.hvoid main(void)int temp1=1,i;while(1)if(!key2)delay2();/按键消抖if(!key2)switch(temp1)case 1:temp1+;i=1;k1=0;k2=1;k3=1;k4=1;P1=0x9F;break;case 2:temp1+;i=2;k1=1;k2=0;k3=1;k4=1;P1=0xD0;break;case 3:temp1=1;i=3;k1=1;k2

31、=1;k3=0;k4=1;P1=0x91;break;if(!key3) delay2(); /延时去抖动if(!key3) /K3键按下选择相应功能if(i=1)while(1)second();if(!key3)delay2();if(!key3)k1=0;k2=1;k3=1;k4=1;P1=0x9f;temp2=0;break;if(i=2)while(1)jsq();if(!key3)delay();if(!key3)k1=1;k2=0;k3=1;k4=1;P1=0xd0;temp3=0;break;if(i=3)while(1)random();if(!key3)delay2();i

32、f(!key3)k1=1;k2=1;k3=0;k4=1;P1=0x91;break;void dis_init(void) /秒表、定时器数码管的初始化k1=1;k2=1;k3=1;k4=0;P1=0x84;dp=1;delay();k1=1;k2=1;k3=0;k4=1;P1=0x84;dp=1;delay();k1=1;k2=0;k3=1;k4=1;P1=0x84;dp=0;delay();k1=0;k2=1;k3=1;k4=1;P1=0x84;dp=1;delay();/数码显示函数void display(unsigned int qian,unsigned int bai,unsig

33、ned int shi,unsigned int ge)k1=0;k2=1;k3=1;k4=1;P1=discodeqian;dp=1;delay();k1=1;k2=0;k3=1;k4=1;P1=discodebai;dp=0;delay();k1=1;k2=1;k3=0;k4=1;P1=discodeshi;dp=1;delay();k1=1;k2=1;k3=1;k4=0;P1=discodege;dp=1;delay();void second(void)int i=-1,j,k;unsigned int recordN; HEAD:dis_init();TMOD=0x01; /定时器T

34、0,方式1TH0=(65536-10000)/256; /定时1ms,并赋初值 TL0=(65536-10000)%256;EA=1;EX0=1;ET0=1;temp2=0;if(key2=0)delay2(); /按键消抖if(!key2)TR0=1;/定时器T0打开while(1)while(TF0) / 采用查询法TF0=0; /溢出标志位软件置0TH0=(65536-10000)/256;TL0=(65536-10000)%256;temp2+;if(temp2=10000) / 计时范围099.99stemp2=0;qian=temp2/1000; /利用整数除法得到千位bai=(t

35、emp2-(1000*qian)/100; /得到百位shi=(temp2-qian*1000-100*bai)/10;/得到十位ge=temp2%10;/利用求余运算得到个位display(qian,bai,shi,ge); /数码管显示相应时间if(!key3)delay2();if(!key3)i+;recordi=temp2; /把记录的时间所对应的/temp值存入数组record中if(!key2)delay2();if(!key2)TR0=0; /再次按下K2键,关闭定时/计数器T0,break;/跳出循环,for(j=0;j<i+1;j+)/依次显示记录好的时间qian=r

36、ecordj/1000;bai=(recordj-(1000*qian)/100;shi=(recordj-qian*1000-100*bai)/10;ge=recordj%10;for(k=0;k<300;k+)display(qian,bai,shi,ge);k1=k2=k3=k4=1;delay2s();goto HEAD; /转到函数头部,相当于复位void jsq(void) /定时器函数与秒表原理相同top:temp3=0;while(1)dis_init();if(!key3)delay2();if(!key3)goto bottom;if(!key2)delay2(); if(!key2)temp3=temp3+1000;while(1)if(key2=0)delay2();if(!key2)temp3+=1000; /每按下K2键一次,定时时/间增加10秒if(temp3=10000) /定时最长90秒temp3=0;qian=temp3/1000;bai=temp3%1000/100;shi=temp3%100/10;ge=temp3%10;display(qian,bai,shi,ge);if(!key3)delay2();if(!key3)goto jishi;jishi:TMOD=0x01; TH1=(65536-10000)/256; TL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论