基于C++实现(控制台)学生程序管理系统
♻️ 资源大小49.3KB➡️资源下载https://download.csdn.net/download/s1t16/87430324学生程序管理系统一、学生程序管理系统程序设计报告团队成员黄继升朱伯翰完成时间 2019 年 12 月二、学生成绩管理系统设计报告2.1 人员组成及分工2.1.1 人员组成及分工2.2 开发背景为了更好的了解学生的学习情况以对学生进行更详细的了解对未来的教学有相应的规划同时为了便于期末总结我们设计了一套学生成绩管理系统。在本次课程设计中操作者根据清单上的提示对于不同的学生进行分数的录入、修改、查询以及获取相应的统计结果并支持数据的输出。2.3 系统功能设计2.3.1 系统功能模块图图 3-1 系统功能模块图2.3.2 系统业务流程图图 3-2 业务流程图2.4 项目创建2.4.1 系统开发环境要求本项目的开发及运行环境要求操作系统windows 7, windows 10开发工具Code Blocks 17.12, Visual Studio Code开发语言C 语言2.4.2 项目创建过程打开 Code Block图 4-1 Code Block 使用界面2.4.2 点击“open an existing project”并选中“Console application”图 4-2 工程创建界面选择 C并点击 next图 4-3 创建 C 工程填写项目名称以及路径。图 4-4 填写项目名称和工程路径直点击 next 默认配置最后点击 Finish 完成工程创建。图 4-4 完成工程创建点击 File-Empty file创建并命名第一个 C 文件并编写代码图 4-4 创建 C 文件2.5 预处理模块设计2.5.1 文件引用# include stdio.h # include string.h # include math.h # include malloc.h # include stdlib.h2.5.2 宏定义# define true 1 # define false 0 # define MAX_LEN 12 /* 字符串最大长度 */ # define STU_NUM 30 /* 最大的学生人数 */ # define COURSE_NUM 6 /* 最大的考试科目数 */ # define LEN sizeof(struct Student) /* 学生结构体所占的字节大小*/2.5.3 定义全局变量int n, m; //输入的学生人数以及考试科目数 int i; //输入菜单选项编号 STU *head; //定义内存中的学生链表头节点2.5.4 函数声明void Print(STU *head, int n, int m)输入参数学生链表学生数考试科目数量输出参数null实现功能输出链表中所有节点void AverSumofEveryStudent(STU *head)输入参数学生链表输出参数null实现功能计算每门课程的总分和平均分void AverSumofEveryCourse(STU *head)输入参数学生链表输出参数null实现功能计算每个学生的总分和平均分void StatisticAnalysis(STU *head, int n, int m)输入参数学生链表学生数考试科目数量输出参数null实现功能按类别及比例输出STUSortbyScore(STUhead, int n)输入参数学生链表学生数输出参数学生链表头结点实现功能按每个学生的总分由高到低排出名次表STUSortbyScore1(STUhead, int n)输入参数学生链表学生数输出参数学生链表头结点实现功能按每个学生的总分由低到高排出名次表STUSortbyNum(STUhead)输入参数学生链表输出参数学生链表头结点实现功能按学号由小到大排出成绩表STUSortbyName(STUhead, int n)输入参数学生链表学生数考试科目数量输出参数学生链表头结点实现功能按姓名的字典顺序排出成绩表STU *Create(int n, int m)输入参数学生数考试科目数量输出参数学生链表头结点实现功能创建链表并录入信息void SearchbyNum(STU *head, int n, int m)输入参数学生链表学生数考试科目数量输出参数null实现功能按学号查询学生排名及其考试成绩void SearchbyName(STU *head, int n, int m)输入参数学生链表学生数考试科目数量输出参数null实现功能按姓名查询学生排名及其考试成绩void WritetoFile(STU *head, int n, int m)输入参数学生链表学生数考试科目数量输出参数null实现功能将每个学生的纪录信息写入文件STUReadfromFile(STUhead, intn, intm)输入参数学生链表学生数考试科目数量输出参数学生链表头结点实现功能从文件中读出每个学生的纪录信息并显示int DeleteFromFile(STUhead, intn, int *m);输入参数学生链表学生数考试科目数量输出参数不存在数据或没有数据返回 0成功删除返回 1实现功能物理删除(删除在文件中的数据)STUgetAllMessageFromFile(STUhead, int count0[], int count1[], int *count2)输入参数学生链表学生数考试科目数量输出参数学生链表头结点实现功能获取文件中所有的学生成绩数据并组成单链表STUModifyScore(STUhead)输入参数学生链表学生数考试科目数量输出参数学生链表头结点实现功能用于修改学生某个科目的成绩信息2.6 模块详细设计2.6.1 成绩录入模块2.6.2 录入新的学生成绩记录临时区功能描述用户在系统主界面输入数字 “1” 进入录入成绩功能根据提示依次输入学生数量、考试科目数量并依次输入每个学生的学号、姓名和各科成绩最后按下回车将成绩提交到临时区。算法流程相关函数int Menu(void); //函数1创建菜单函数 STU *Create(int n, int m); //函数10创建链表并录入信息测试结果2.6.3 将临时区数据保存到文件中功能描述用户在系统主界面输入数字 “12” 即可将临时区的学生成绩信息保存到 student.txt 文件中算法流程相关函数void WritetoFile(STU *head, int n, int m); //函数13将每个学生的纪录信息写入文件测试结果2.6.4 成绩导出模块2.6.5 导出未保存的学生成绩信息临时区功能描述用户在系统主界面输入数字 “11” 进入临时区数据导出模块此时界面会输出仍未保存的学生成绩数据或临时区没有数据的提示信息。算法流程相关函数void Print(STU *head, int n, int m); //函数2打印函数测试结果2.6.6 导出已保存的学生成绩信息文件功能描述用户在系统主界面输入数字 “12” 进入文件数据导出模块此时界面会输出保存在 student.txt 的所有学生成绩。如果文件不存在或没有数据则会输出 “student.txt 不存在或没有数据的提示信息。算法流程相关函数STU *ReadfromFile(STU *head, int *n, int *m); //函数14从文件中读出每个学生的纪 录信息并显示 void Print(STU *head, int n, int m); //函数2打印函数void Print(STU *head, int n, int m);测试结果2.6.7 排序模块根据成绩总分的升序、降序进行排序功能描述用户在系统主界面输入“4”进入降序排列输入“5”进入升序排列。算法流程首先调用 getAllMessageFromFile 函数从文件读取已经存入的信息获得链表的头结点再遍历链表将总分作为对比依据进行冒泡排序最后输出。相关函数STUSortbyScore(STUhead, int n); //函数 6按每个学生的总分由高到低排出名次表STUSortbyScore1(STUhead, int n); //函数 7按每个学生的总分由低到高排出名次表测试结果根据学号的升序进行排序功能描述用户在系统主界面输入“6”进入。算法流程首先调用 getAllMessageFromFile 函数从文件读取已经存入的信息获得链表的头结点再遍历链表将学号作为对比依据进行冒泡排序最后输出。相关函数与 7.1 的算法相似测试结果根据学生姓名的字典序进行排序功能描述用户在系统主界面输入“7”进入。算法流程首先调用 getAllMessageFromFile 函数从文件读取已经存入的信息获得链表的头结点再遍历链表将姓名首字母的字典序作为对比依据进行冒泡排序最后输出。相关函数STUSortbyNum(STUhead); //函数 8按学号由小到大排出成绩表测试结果2.7 UI 界面设计模块功能描述展示操作界面算法流程主界面根据序号展示相关操作使用*作为边框具体操作界面首先清屏以实现更加简洁的展示便于操作并使用*号分割相关函数int Menu(void); //函数 1创建菜单函数测试结果2.8 条件查询模块2.8.1 按学生学号查询排名及其考试成绩功能描述用户在系统主界面输入数字 “8” 进入按学生学号查询排名及其考试成绩此时按照界面提示输入查询的学号。如果学号不存在或 student.txt 没有数据则会输出 “抱歉没有找到相关记录的提示信息。算法流程相关函数//函数11按学号查询学生排名及其考试成绩 void SearchbyNum(STU *head, int n, int m); //函数16获取文件中所有的学生成绩数据并组成单链表 STU *getAllMessageFromFile(STU *head, int count0[], int count1[], int *count2);测试结果2.8.2 按学生姓名查询排名及其考试成绩功能描述用户在系统主界面输入数字 “9” 进入按学生学号查询排名及其考试成绩此时按照界面提示输入查询的姓名。如果学号不存在或 student.txt 没有数据则会输出 “抱歉没有找到相关记录的提示信息。算法流程相关函数//函数12按姓名查询学生排名及其考试成绩 void SearchbyName(STU *head, int n, int m); //函数2打印函数 void Print(STU *head, int n, int m);测试结果2.9 成绩修改模块功能描述用户在系统主界面输入数字 “16” 此时按照界面提示输入即将修改的记录所对应的学号。如果学号不存在则会输出 “抱歉没有找到相关记录的提示信息。否则系统会打印出该学号对应的成绩记录并提示你需要修改的是学号、姓名还是科目成绩。如果是学号则输入新的学号进行提交如果是姓名则输入新的姓名并进行提交如果是科目成绩则先输入是该科目的序号再输入新的分数进行提交。算法流程相关函数//函数17 用于修改学生成绩信息 STU *ModifyScore(STU *head); //函数16获取文件中所有的学生成绩数据并组成单链表 STU *getAllMessageFromFile(STU *head, int count0[], int count1[], int *count2);测试结果2.10 成绩删除功能描述用户在系统主界面输入数字 “15” 此时按照界面提示输入即将删除的记录所对应的学号。如果学号不存在则会输出 “抱歉没有找到相关记录的提示信息。否则系统将会删除文件中该学号所在的成绩记录并打印出删除成功的提示。算法流程相关函数//函数15: 物理删除(删除在文件中的数据) int DeleteFromFile(STU *head, int *n, int *m);测试结果2.11 成绩统计计算2.11.1 计算并输出每门课程的总分和平均分功能描述用户在系统主界面输入数字 “2” 系统会输出每一门课程的所有学生的总分和平均分算法流程相关函数函数 3计算每门课程的总分和平均分void AverSumofEveryStudent(STU *head); //函数16获取文件中所有的学生成绩数据并组成单链表 STU *getAllMessageFromFile(STU *head, int count0[], int count1[], int *count2);测试结果2.11.2 计算并输出每位学生的总分和平均分功能描述用户在系统主界面输入数字 “3” 系统会输出每一门课程的所有学生的总分和平均分算法流程相关函数//函数4计算每个学生的总分和平均分 void AverSumofEveryCourse(STU *head); //函数16获取文件中所有的学生成绩数据并组成单链表 STU *getAllMessageFromFile(STU *head, int count0[], int count1[], int *count2);测试结果2.11.3 对每门课程的成绩情况进行分段统计功能描述用户在系统主界面输入数字 “10” 系统会输出按课程得分为 100、9099、80 89、7079、6069 和不及格学生的人数以及所占百分比算法流程相关函数//函数5按类别及比例输出 void StatisticAnalysis(STU *head, int n, int m); //函数16获取文件中所有的学生成绩数据并组成单链表 STU *getAllMessageFromFile(STU *head, int count0[], int count1[], int *count2);测试结果2.12 项目创新点该项目的亮点在于之前对学生的成绩进行各种条件的排序时由于单链表不像数组那样可以从后往前进行遍历注一开始没有专门去设置尾指针所以前面已经写好的代码比较多后面也不好为了增加个尾指针而进行更改因此为了能够对单链表引入快速排序算法提高排序效率所以我们的具体思路如下两个指针 p、q 都从头结点开始往后遍历, 开始的时候 p 指针指向头结点(key), q 指针指向 p 的下一个结点, q 指针从前往后查找比 key 值小的元素, 当 q 指针遇到比 key 值小的元素的时候, p 前进一位, 交换 p、q 指向的元素, 如果 q 指针遇到的元素比 key 大, 则 p 指针不动, q 指针继续向前查找, 直到 q 指针查找到链表末端. 显然 q 指针比 p 指针移动速度快, 这就保证了 p 指针前面的元素都比 key 小, 此时 p 指针指向的位置就是 key 对应的元素在排序后的正确位置, 也就是 partition 的位置, 因此交换 key 对应的元素与 p 指针当前指向的元素, 并以此位置作为 partition 的临界点。2.13 收获和建议黄继升这学期的程序实践课程设计我们小组决定做一个学生成绩管理系统。自大一大二上完数据结构以及操作系统等课程之后便很少继续深入 C 语言的学习平时用的较多的是其他编程语言因此通过这次大作业我们又重新对 C 语言进行了一次比较系统的复习重点是指针、链表和文件 I/O 这一块是 C 语言重点和难点同时经过这次课程设计的开发加深了对这一块内容的理解。但是由于时间关系最后的成果没能做到尽善尽美该有的 bug 也没有能够消除比如一次性录入超过 10 位学生在写入到文件之前打印出这 10 位学生的信息时最后两位学生的总分和平均分会出现一堆数字可是写到文件里再读出却是正常的这一点真的很困惑但最终也没有解决。另外对学生成绩的修改采用的方法也比较极端是通过先将文件信息全部读到内存再进行修改最后把修改结果重新覆盖源文件。这是我们这次开发存在的两个最大的不足之处此外 UI 界面的设计也值得吐槽。但是通过这次开发我们小组也是重新对基础语言进行了一次系统的复习虽然我现在基本用的都是 python 和 Java但是这些编程语言的底层还是用 C/C 来实现的对 C 语言基础的巩固将会有助于我今后对开发框架底层、JVM 和数据库等有更深的了解让自己的知识积累更加丰富。朱伯翰这次的小组作业是建立一个学生成绩管理系统我和搭档掌握了从功能设计开始构思整体框架掌握了数组指针链表排序文件 I/O 等相关原理以及程序的编写。期间查阅了相关的书籍和资料也阅读了一些 C 语言相关的经典书籍获得了对 C 语言更深刻的理解。程序的编写过程中难免会出现一些 bug这也更利于去查找相关的资料以获得更官方和清晰的解释从而用最优的方法进行编写。比如C 语言内部数组的首地址是不可以被更改的所以不能用赋值的方式去交换。这样的困难会让自己积累经验对 C 语言的掌握更深。