1、C语言学生管理系统实验设计报告吉 林 大 学实 验 设 计 设计题目: 学 院: 专业班级: 姓 名: 学 号: 指导教师: 学生成绩管理系统一、 设计目的1、掌握对链表、结构体、指针、文件的操作和C语言算法的应用。2、用程序实现动态链表的建立、查找、修改、删除、插入、输出、排序,或结构体数组的输入、修改、删除、插入、输出,或文件记录的添加、修改、删除、排序(包括对文件记录按某个数据项排序)、查询、插入。二、 设计过程1. 需求分析1)、系统界面需求进入系统时应当出现相对人性化的字符界面或图形界面,提供菜单选项,按提示选择序号执行相应的功能,输入输出数据或操作成功时要有相应提示信息,此外还要提
2、供帮助信息,如系统的功能介绍等,提供系统信息或程序信息,如学生、详细信息等。2)、系统功能需求对设计题目进行分析,可知系统主要功能可以有下面几种,而且各种功能互相组合,形成或构成新的功能。、输入功能。第一次可通过在内存中新建或创建动态链表输入学生的成绩记录和其他数据记录,而且随时可以退出输入,既可在退出时可自动保存或提示保存或输入完毕后返回主菜单选择“Save the file”命令进行手动保存到硬盘,也可以在输入过程中自动保存。如果以前已经建立过动态链表且已经保存到文件中,可先选择“Load the file”(相当于打开文件、读取文件),再插入新的记录到动态链表。、删除功能。根据学号、姓名
3、或其他数据项在动态链表中查找并删除一个学生的成绩记录。、显示记录。直接输出已按某数据项排序(学号顺序)的动态链表中所有学生的记录于屏幕上显示。、查找功能。查找的目的可能是查看学生数据、修改数据或删除数据。查找的方式有精确查找和模糊查找两种。精确查找,指根据学号、姓名或其他数据项在动态链表中查找并显示一个学生的成绩记录。模糊查找,指根据学号、姓名或其他数据项的逻辑组合条件在动态链表中查找并显示符合条件的学生的成绩记录。查找的结果可以返回地址(指针)用于查看、修改或删除数据插入功能。插入或添加一个学生的成绩记录到已有的动态链表中,比如载入文件后的动态链表或刚刚新建的动态链表。、保存文件。将新建的或
4、修改的动态链表的所有数据写入(或存入、存到)二进制文件中。、载入文件。相当于打开文件并读取文件中所有学生的数据(包括班级、学号、姓名、成绩等)到动态链表。、统计功能。根据录入的数据项在动态链表中计算学生成绩(包括总分,平均分以及各分数段的人数及其信息)。可按成绩、学号或姓名排序,而成绩排序又可按单科成绩或总成绩排序。、插入功能。插入或添加一个学生的成绩记录到已有的动态链表中,比如载入文件后的动态链表或刚刚新建的动态链表。、退出功能。退出系统或退出程序,可增加一个退出函数语句,在退出时可提示保存文件,防止数据丢失。2. 概要设计在需求分析的基础上,确定系统总体框架(即系统功能结构图、系统模块结构
5、图)。 系统各个功能的详细解释。1.Enter list创建链表。输入学生的成绩和其他信息,并且自动计算总成绩和平均成绩2. Delete a record from list删除记录。根据学号在动态链表中查找并删除一个学生的成绩记录。3.Print list显示记录。自动按总成绩从高到低排序后显示动态链表中所有学生的成绩记录。4.Search record on name查找记录。根据学号在动态链表中查找并显示一个学生的成绩记录。5.Save the file保存数据。将动态链表的所有数据写入(或存入、存到)二进制文件中。6.Load File读取数据。读取文件中所有学生的数据(包括班级、学
6、号、姓名、成绩等)到动态链表。7.Compute the score 统计数据。将动态链表的所有学生数据进行各分数段的统计。8.Insert record to list插入记录。在动态链表中插入一个学生的成绩记录。9.Quit 退出。如菜单返回值为0程序结束。3. 详细设计1)、数据结构设计系统使用了结构体类型存储学生的成绩记录和其他记录。typedef struct S1 char no9;/*学号*/ char name15; /*姓名*/ char sex; /*性别*/ int age; /*年龄*/ int score4; /*成绩*/ float sum; /*总分*/ floa
7、t average; /*平均分*/ int order; /*排名*/ struct S1 *next;STUDENT;2)、算法结构设计系统使用了以下函数来实现系统各个模块的功能。函数名称函数功能student *enter_list()创建链表,完成数据录入功能 void compute_the_score()对学生成绩排序并确定名次void insert_record()按学号插入一个结点数据void print_list()显示所有已经建立好的节点的节点号和该节点中数据项内容void search_record()按学号查找并显示一个结点数据void delete_a_record(
8、)按学号查找并删除一个结点数据void save_the_file()保存数据到文件模块void load_the_file()加载存储在外部介质的文件到内存或导入信息模块void init()显示菜单并获得用户键盘输入的选项*void main()程序从主函数开始执行 系统主要功能的实现过程和方法。创建链表。在界面状态下,输入1后调用student *enter_list()函数创建动态链表,即提示输入初始的学生信息,其中包括学生的学号、姓名、性别和数学、英语、物理、历史的成绩,若输入为0退出返回主菜单。输入完成后,系统调用void compute_the_score()函数计算每个学生的总
9、成绩和平均成绩,还可以调用void save_the_file() 函数对指定的文件进行写操作,把输入到动态链表的所有学生信息保存到文件中。插入记录。在界面状态下,输入8后调用void insert_record() 函数在动态链表中插入一个学生的成绩记录,并且链表结点数加1。在插入记录过程中若学号输入0则返回主菜单。显示记录。在界面状态下,输入3后先调用void print_list() 函数对学生成绩排序并确定名次,而这个函数运用冒泡法进行排序,排序完毕后再调用void print_list() 函数显示所有已经建立好的节点的节点号和该节点中数据项内容,即按总成绩从高到低排序后显示动态链表
10、中所有学生的成绩记录。输出所有记录到屏幕上显示后自动则返回主菜单。查找记录。在界面状态下,输入4后调用void search_record()函数,即先用一个指针变量接收输入的学号,再与动态链表中各结点的学号一一比较,如果没有则返回失败信息,如果找到就将输出此学生全部信息到屏幕上显示出来。在查找记录过程中若学号输入0则提示找不到并返回主菜单。删除记录。在界面状态下,输入2后调用void delete_a_record()函数,即先用一个变量接收输入的学号,再与动态链表中各结点的学号一一比较,如果没有则返回失败信息,如果找到就将此记录都向前移一位,并且链表结点数减1。在删除记录过程中若学号输入0
11、则提示找不到并返回主菜单。保存数据。在界面状态下,输入5后调用void save_the_file() 函数,先用一个文件(FILE)类型结构体的指针变量fp接收fopen(文件名,文件使用方式)函数的返回值(地址值),若打开操作失败,其返回值为NULL(即地址值为0,是一个无效的指向)。若打开操作成功,返回值为指向被打开文件的文件信息区(结构体变量)的起始地址,该返回值要立即赋值给文件类型指针变量(例:/FILE *fp)保存起来,否则fopen函数返回值的丢失会导致无法对被打开的文件进行操作。最后使用fclose(fp)函数关闭文件。读取数据。在界面状态下,输入6后调用void load_
12、the_file()加载存储在外部介质的文件到内存或导入信息模块读取文件中所有学生的数据(包括班级、学号、姓名、成绩等)到动态链表。退出。在界面状态下,输入9后用一个函数void quit()来实现,可首先提示将信息保存到文件中,释放动态创建的内存空间,再退出此程序。3)流程图4. 代码设计#include#include#define TOTALSTU 10typedef struct S1long no;/*学号*/char name15; /*姓名*/char sex; /*性别*/int age; /*年龄*/int score4; /*成绩*/float sum; /*总分*/flo
13、at average; /*平均分*/int order; /*排名*/struct S1 *next;student;int n;char flag=0;student *head; /*链表头结点指针*/char filename12;student *enter_list() /*建立链表,输入成批学生信息*/student *p1,*p2;n=0;p1=p2=(student*)malloc(sizeof(student);printf( Please input student info: (Press 0 to end) n);printf(Num:);scanf(%ld,&p1-
14、no);if(p1-no=0) return(0);printf(Name:);scanf(%c,p1-name);gets(p1-name);printf(Age:);scanf(%d,&p1-age);printf(Sex (m/f):);scanf(%c,&p1-sex);scanf(%c,&p1-sex);while(p1-sex!=f&p1-sex!=m)printf(Error!please input again:n);scanf(%c,&p1-sex);scanf(%c,&p1-sex);printf(Math:);scanf(%d,&p1-score0);printf(Eng
15、lish:);scanf(%d,&p1-score1);printf(Physics:);scanf(%d,&p1-score2);printf(History:);scanf(%d,&p1-score3);head=NULL;while(p1-no!=0) /*输入为0时结束*/n=n+1;if(n=1)head=p1;else p2-next=p1;p2=p1;p1=(student*)malloc(sizeof(student);printf(nNum:);scanf(%ld,&p1-no);if(p1-no=0) break;printf(Name:);scanf(%c,p1-name
16、);gets(p1-name);printf(Age:);scanf(%d,&p1-age);printf(Sex(m/f):);scanf(%c,&p1-sex);scanf(%c,&p1-sex);while(p1-sex!=f&p1-sex!=m)printf(Error!please input again:n);scanf(%c,&p1-sex);scanf(%c,&p1-sex);printf(nMath:); scanf(%d,&p1-score0);printf(English:); scanf(%d,&p1-score1);printf(Physics:);scanf(%d,
17、&p1-score2);printf(History:);scanf(%d,&p1-score3);p2-next=NULL;return(head);void insert_record() /*插入学生节点*/student *p0;student *p1;student *p2;p0=(student*)malloc(sizeof(student);p1=p2=head; /*p1指向原链表*/printf(no:* name:* sex:* age:* score:*,*,*,*n); /*插入学生记录,保存在study中*/printf(Num:);scanf(%ld,&p0-no)
18、;printf(Name:);scanf(%c,p0-name);gets(p0-name);printf(Sex(m/f):);scanf(%c,&p0-sex);printf(Age:);scanf(%d,&p0-age);printf(Math:);scanf(%d,&p0-score0);printf(English:);scanf(%d,&p0-score1);printf(Physics:);scanf(%d,&p0-score2);printf(History:);scanf(%d,&p0-score3);printf(Num:%ld Name:%s Sex:%c Age:%d
19、Record: Math:%d,English:%d,Physics%d,History:%dn,p0-no,p0-name,p0-sex,p0-age,p0-score0,p0-score1,p0-score2,p0-score3);if(head=NULL) head=p0;p0-next=NULL; elsewhile(p0-nop1-no)&(p1-next!=NULL) /*按Num升序插入*/p2=p1;p1=p1-next;if(p0-nono)if(head=p1) head=p0;else p2-next=p0;p0-next=p1;elsep1-next=p0;p0-nex
20、t=NULL;n=n+1;void search_record() /*根据学生学号,查找学生记录*/student *p;long number;p=head;if(head=NULL)printf(n*Enterlist is empty!*n);return;elseprintf(Please input the Num you want to search:);scanf(%ld,&number);while(p-no!=number&p-next!=NULL)p=p-next;if(p-no=number)printf(n* found it *n);printf(Num:%ld N
21、ame:%s Sex:%c Age:%d Record:Math:%d,English:%d,Physics:%d,History:%dn,p-no,p-name,p-sex,p-age,p-score0,p-score1,p-score2,p-score3); /*查找完成后显示*/else printf(%ld cant be foundn,number);void delete_a_record()student *p1,*p2;long no;if(head=NULL)printf(nEnterlist is empty!n);return;printf(Please input th
22、e Num you want to delete:); /*输入要删去记录的学生学号*/scanf(%ld,&no);p1=head;while(no!=p1-no&p1-next!=NULL) /*与链表中的学生学号依次比较*/p2=p1;p1=p1-next;if(no=p1-no) /*找到了,将该节点删去*/if(p1=head)head=p1-next;else p2-next=p1-next;printf(has delete:%ldn,no);n=n-1;else printf(%ld not been found!n,no); /*找不到,提示*/void print_list
23、()student *p;printf(There are %d recordsn,n);p=head;if(head!=NULL)doprintf( Student: Num:%-5ld Name:%-10s Sex:%c Age:%dn,p-no,p-name,p-sex,p-age);printf( Record: Math:%-5d English:%-10d Physics:%d History:%dn,p-score0,p-score1,p-score2,p-score3);printf(n);p=p-next; while(p!=NULL);void compute_the_sc
24、ore() /*整理学生成绩*/int i,j,m,k=0;float thesum=0;student *aTOTALSTU;student *p0,*p ;p0=head; /* 用指针P0调用动态链表 */while(p0!=NULL) /*计算各节点总分及平均成绩*/thesum=0;for(j=0;jscorej;p0-sum=thesum;p0-average=(float)(p0-sum)/4;p0=p0-next;p0=head;while(p0!=NULL) /*将动态链表各节点地址赋给指针数组 */ak+=p0;p0=p0-next;m=k;ak=NULL;for(i=0;
25、im-1;i+) /*冒泡法排序,使各节点按总分降序排列 */for(j=0;jm-1-i;j+)if(*aj).sum(*aj+1).sum)p=aj;aj=aj+1;aj+1=p;for(i=0,j=1;im;i+) /*依次给个节点填入总分名次 */(*ai).order=j+;printf(* Sort by records: * n);for(i=0;i=90: *n);for(i=0;i=90) printf(* Num:%ld * Name:%s Sex:%c Age:%dn,(*ai).no,(*ai).name,(*ai).sex,(*ai).age);printf(* Re
26、cord * Math:%d English:%d Physics:%d History:%d n,(*ai).score0,(*ai).score1,(*ai).score2,(*ai).score3);printf(nn* The list of average =80: *n);for(i=0;i=80) printf(* Num:%ld * Name:%s Sex:%c Age:%dn,(*ai).no,(*ai).name,(*ai).sex,(*ai).age);printf(* Record * Math:%d English:%d Physics:%d History:%d n,(*ai).score0,(*ai).score1,(*ai).score2,(*ai).score3);printf(nn* The list of average =70: *n);for(i=0;i=70) printf(* Num:%ld * Name:%s Sex:%c Age:%dn,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1