900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 【C语言课程设计】【C语言】学生成绩管理系统

【C语言课程设计】【C语言】学生成绩管理系统

时间:2023-05-01 12:18:31

相关推荐

【C语言课程设计】【C语言】学生成绩管理系统

学生数据由学号、姓名、班级、三门课(数学、英语、计算机)的成绩和平均成绩构成。

功能要求:

(1)添加学生的记录

(2)查询学生记录(分别按学号和姓名)

(3)对学生数据排序(分别按平均成绩和计算机成绩的降序)

(4)删除学生记录

(5)修改学生记录

(6)班级成绩分析(各科平均成绩、最高分、最低分、及格率)

(7)输出学生信息表

list.h

#ifndef list_h#define list_h#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>typedef struct nNode Node;struct nNode{// 向上指针Node* nUp;// 向下指针Node* nDown;// 学号int iId;// 班级char* pcClass;// 姓名char* pcName;// 数学float fMath;// 英语float fEng;// 计算机float fCmp;// 平均分float fAver;};typedef struct{Node* nTop;Node* nBottom;int iSize;} List;// 新建节点Node* Node_new(int iId, char* pcClass, char* pcName, float fMath, float acEng, float acCmp);// 删除节点void Node_delete(Node* nNode);// 新建链表List* List_new(void);// 删除链表void List_delete(List* lList);// 节点从链表顶部加入void List_pushTop(List* lList, Node* nNewNode);// 节点从链表顶部取出Node* List_popTop(List* lList);// 节点从链表底部加入void List_pushBottom(List* lList, Node* nNewNode);// 节点从链表底部取出Node* List_popBottom(List* lList);// 节点从链表指定位置插入void List_insert(List* lList, Node* nNewNode, int iIndex);// 从链表中移除指定节点void List_remove(List* lList, Node* nOldNode);// 这个节点在链表是第几个节点int getIndex(List* lList, Node* nOldNode);// 按平均分排序void List_sortByAver(List* lList);// 按计算机成绩排序void List_sortByCmp(List* lList);// 按学号输出void List_printById(List* lList);// 按姓名输出void List_printByName(List* lList);#endif // list_h

list.c

#include"list.h"// 新建节点Node* Node_new(int iId, char* pcClass, char* pcName, float fMath, float fEng, float fCmp){int iSize;Node* nNode = (Node*)malloc(sizeof(Node));// 设置向上指针nNode->nUp = NULL;// 设置向下指针nNode->nDown = NULL;// 设置学号nNode->iId = iId;// 设置班级if(pcClass != NULL)iSize = strlen(pcClass);elseiSize = 0;if(iSize != 0){nNode->pcClass = (char*)malloc(sizeof(char)*(iSize) + 1);strcpy(nNode->pcClass, pcClass);nNode->pcClass[iSize] = '\0';}// 设置姓名if(pcName != NULL)iSize = strlen(pcName);elseiSize = 0;if(iSize != 0){nNode->pcName = (char*)malloc(sizeof(char)*(iSize) + 1);strcpy(nNode->pcName, pcName);nNode->pcName[iSize] = '\0';}// 设置数学成绩nNode->fMath = fMath;// 设置英语成绩nNode->fEng = fEng;// 设置计算机成绩nNode->fCmp = fCmp;// 设置平均成绩nNode->fAver = (fMath + fEng + fCmp)/3.0;return nNode;}// 删除节点void Node_delete(Node* nNode){// 释放字符串空间free(nNode->pcClass);free(nNode->pcName);// 释放节点空间free(nNode);}// 新建链表List* List_new(void){// 新建链表数据List* lList = (List*)malloc(sizeof(List));// 链表节点个数初始化为 0lList->iSize = 0;// 新建顶部节点,顶部节点是空节点lList->nTop = Node_new(0, "", "", 0.0, 0.0, 0.0);// 新建底部节点,底部节点也是空节点,这样写容易组织代码lList->nBottom = Node_new(0, "", "", 0.0, 0.0, 0.0);// 顶部节点的 nDown 指针连接到底部节点lList->nTop->nDown = lList->nBottom;// 底部节点的 nUp指针连接到顶部节点lList->nBottom->nUp = lList->nTop;return lList;}// 删除链表void List_delete(List* lList){Node* nNode;// 逐个删除中间的节点for(; lList->iSize>0; ){// 获取顶部节点的下一个节点nNode = lList->nTop->nDown;// 顶部节点的 nDown 指针连接到顶部节点的下下节点lList->nTop->nDown = lList->nTop->nDown->nDown;// 删除节点Node_delete(nNode);// 节点个数减 1lList->iSize --;}// 删除顶部节点if(lList->nTop != NULL)Node_delete(lList->nTop);// 删除底部节点if(lList->nBottom != NULL)Node_delete(lList->nBottom);// 删除链表数据free(lList);}// 节点从链表顶部加入void List_pushTop(List* lList, Node* nNewNode){// 新节点 nUp 指针连接到链表顶部节点nNewNode->nUp = lList->nTop;// 新节点 nDown 指针连接到链表顶部节点的下一节点nNewNode->nDown = lList->nTop->nDown;// 链表顶部节点的下一节点 nUp 指针连接到新节点lList->nTop->nDown->nUp = nNewNode;// 链表顶部节点 nDown 指针连接到新节点lList->nTop->nDown = nNewNode;// 节点个数加 1lList->iSize ++;}// 节点从链表顶部取出Node* List_popTop(List* lList){// 备份将要取出的节点Node* nNode = lList->nTop->nDown;if(lList->iSize > 0){// 链表顶部节点下下节点的 nUp 指针连接到链表顶部节点lList->nTop->nDown->nDown->nUp = lList->nTop;// 链表顶部节点的 nDown 指针连接到下下节点lList->nTop->nDown= lList->nTop->nDown->nDown;nNode->nUp = NULL;nNode->nDown = NULL;// 节点个数减 1lList->iSize --;}elseprintf("%s\n", "List_popTop() 函数报错,此链表是空的,没有节点可取出。");return nNode;}// 节点从链表底部加入void List_pushBottom(List* lList, Node* nNewNode){// 新节点 nDown 指针连接到链表底部节点nNewNode->nDown = lList->nBottom;// 新节点 nUp 指针连接到链表底部节点的上一节点nNewNode->nUp = lList->nBottom->nUp;// 链表底部节点的上一节点 nDown 指针连接到新节点lList->nBottom->nUp->nDown = nNewNode;// 链表底部节点 nUp 指针连接到新节点lList->nBottom->nUp = nNewNode;// 节点个数加 1lList->iSize ++;}// 节点从链表底部取出Node* List_popBottom(List* lList){// 备份将要取出的节点Node* nNode = lList->nBottom->nUp;if(lList->iSize > 0){// 链表底部节点上上节点的 nDown 指针连接到链表底部节点lList->nBottom->nUp->nUp->nDown = lList->nBottom;// 链表底部节点的 nUp 指针连接到上上节点lList->nBottom->nUp = lList->nBottom->nUp->nUp;nNode->nUp = NULL;nNode->nDown = NULL;// 节点个数减 1lList->iSize --;}elseprintf("%s\n", "List_popBottom() 函数报错,此链表是空的,没有节点可取出。");return nNode;}// 节点从链表指定位置插入void List_insert(List* lList, Node* nNewNode, int iIndex){Node* nOldNode = lList->nTop->nDown;int i;for(i=0; i<iIndex; i++)nOldNode = nOldNode ->nDown;// 把 nNewNode 节点插到 nOldNode 节点上面nNewNode->nUp = nOldNode->nUp;nNewNode->nDown = nOldNode;nOldNode->nUp->nDown = nNewNode;nOldNode->nUp = nNewNode;// 节点个数加 1lList->iSize ++;}// 从链表中移除指定节点void List_remove(List* lList, Node* nOldNode){// 断开 nOldNode节点的前后链接nOldNode->nUp->nDown = nOldNode->nDown;nOldNode->nDown->nUp = nOldNode->nUp;// 节点个数减 1lList->iSize --;}// 这个节点在链表是第几个节点int getIndex(List* lList, Node* nOldNode){int i, iSize = lList->iSize;Node* nNode = lList->nTop;for(i=0; i<iSize ; i++){nNode = nNode->nDown;if(nOldNode == nNode)return i;}return -1;}// 按平均分排序void List_sortByAver(List* lList){Node* nNode = NULL;Node* nMaxNode = NULL;int i, j, iSize = lList->iSize;float fMax;for(i=0; i<iSize; i++){fMax = 0.0;nNode = lList->nTop;for(j=iSize-i; j>0; j--){nNode = nNode->nDown;if(nNode->fAver > fMax){fMax = nNode->fAver;nMaxNode = nNode;}}// 把最高平均分节点移除List_remove(lList, nMaxNode);// 把最高平均分节从链表底部加入List_pushBottom(lList, nMaxNode);}}// 按计算机成绩排序void List_sortByCmp(List* lList){Node* nNode = NULL;Node* nMaxNode = NULL;int i, j, iSize = lList->iSize;float fMax;for(i=0; i<iSize; i++){fMax = 0.0;nNode = lList->nTop;for(j=iSize-i; j>0; j--){nNode = nNode->nDown;if(nNode->fCmp > fMax){fMax = nNode->fCmp;nMaxNode = nNode;}}// 把最高计算机分节点移除List_remove(lList, nMaxNode);// 把最高计算机分节从链表底部加入List_pushBottom(lList, nMaxNode);}}// 按学号输出void List_printById(List* lList){int iId;for(; ;){printf("%s\n", "请输入学号,如果要退出,请输入 0:");scanf("%d", &iId);// 如果输入的是 0 退出循环if(iId == 0)return;// 得到顶部节点指针Node* nNode = lList->nTop;int i, iSize = lList->iSize;for(i=0; i<iSize; i++){nNode = nNode->nDown;if(nNode->iId == iId){// 输出学号printf("学号:%d\t", nNode->iId);// 输出班级printf("班级:%s\t", nNode->pcClass);// 输出姓名printf("姓名:%s\t", nNode->pcName);// 输出数学成绩printf("数学:%.1f\t", nNode->fMath);// 输出英语成绩printf("英语:%.1f\t", nNode->fEng);// 输出计算机成绩printf("计算机:%.1f\t", nNode->fCmp);// 输出平均成绩printf("平均分:%.2f\n", nNode->fAver);return;}}printf("%s\n", "没有此学生的记录,请重新输入:");}}// 按姓名输出void List_printByName(List* lList){char acName[32];name:printf("%s\n", "请输入姓名,如果要退出,请输入 NULL:");scanf("%s", &acName[0]);// 如果输入的是 NULL 退出循环if((acName[0] == 'N') && (acName[1] == 'U') && (acName[2] == 'L') && (acName[3] == 'L'))return;// 得到顶部节点指针Node* nNode = lList->nTop;int i, iSize = lList->iSize;for(i=0; i<iSize; i++){nNode = nNode->nDown;if(strCmp(nNode->pcName, acName)){// 输出学号printf("学号:%d\t", nNode->iId);// 输出班级printf("班级:%s\t", nNode->pcClass);// 输出姓名printf("姓名:%s\t", nNode->pcName);// 输出数学成绩printf("数学:%.1f\t", nNode->fMath);// 输出英语成绩printf("英语:%.1f\t", nNode->fEng);// 输出计算机成绩printf("计算机:%.1f\t", nNode->fCmp);// 输出平均成绩printf("平均分:%.2f\n", nNode->fAver);return;}}printf("%s\n", "没有此学生的记录,请重新输入:");goto name;}

oper.h

#ifndef oper_h#define oper_h#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include"list.h"// 菜单函数int menu(char* acOptions);// 字符串比较_Bool strCmp(char* acStrA, char* acStrB);// 添加记录void addRec(List* lList);// 查询记录void srchRec(List* lList);// 排序记录void sortRec(List* lList);// 删除记录void delRec(List* lList);// 修改记录void modRec(List* lList);// 分析记录void analRec(List* lList, float fPassLine);// 输出记录void oputRec(List* lList);#endif // oper_h

oper.c

#include"oper.h"// 菜单函数int menu(char* acOptions){int iNum;printf("%s\n", acOptions);scanf("%d", &iNum);return iNum;}// 字符串比较_Bool strCmp(char* acStrA, char* acStrB){int i;for(i=0; ; i++){if(acStrA[i] != acStrB[i])return 0;else if((acStrA[i] == '\0') && (acStrB[i] == '\0'))return 1;}}// 添加记录void addRec(List* lList){char acClass[32], acName[32];int iId = 0;float fMath = 0.0, fEng = 0.0, fCmp = 0.0;Node* nNode = NULL;for(; ;){printf("%s\n", "请输入学号,如果输入完成,请输入 0:");scanf("%d", &iId);// 如果输入的是 0 退出循环if(iId == 0)return;printf("%s\n", "请输入班级:");scanf("%s", &acClass);printf("%s\n", "请输入姓名:");scanf("%s", &acName);printf("%s\n", "请输入数学成绩:");scanf("%f", &fMath);printf("%s\n", "请输入英语成绩:");scanf("%f", &fEng);printf("%s\n", "请输入计算机成绩:");scanf("%f", &fCmp);// 新建节点nNode = Node_new(iId, acClass, acName, fMath, fEng, fCmp);// 节点从底部加入链表List_pushBottom(lList, nNode);}}// 查询记录void srchRec(List* lList){int iMenu = 0;for(; ;){iMenu = menu("**************************************************************************\n1------按学号查询 2------按姓名查询 3------退出查询\n**************************************************************************\n请输入选项所对应的数字:\n");switch (iMenu){case 1:List_printById(lList);break;case 2:List_printByName(lList);break;case 3:// 退出查询return;default:printf("%s\n", "您输入的选项不存在,请重新输入。");}}}// 排序记录void sortRec(List* lList){int iMenu = 0;for(; ;){iMenu = menu("**************************************************************************\n1------按平均成绩排序 2------按计算机成绩排序 3------退出排序\n**************************************************************************\n请输入选项所对应的数字:\n");switch (iMenu){case 1:List_sortByAver(lList);printf("%s\n", "按平均成绩排序完成。");oputRec(lList);break;case 2:List_sortByCmp(lList);printf("%s\n", "按计算机成绩排序完成。");oputRec(lList);break;case 3:// 退出排序return;default:printf("%s\n", "您输入的选项不存在,请重新输入。");}}}// 删除记录void delRec(List* lList){char acName[32];int i, iSize;Node* nNode = NULL;for(; ;){printf("%s\n", "请输入要删除学生的姓名,如果要退出删除,请输入 NULL:");scanf("%s", &acName[0]);// 如果输入的是 NULL 退出函数if((acName[0] == 'N') && (acName[1] == 'U') && (acName[2] == 'L') && (acName[3] == 'L'))return;// 获取链表节点总数iSize = lList->iSize;// 获取顶部节点指针nNode = lList->nTop;for(i=0; i<iSize; i++){nNode = nNode->nDown;if(strCmp(nNode->pcName, acName)){// 从链表中移除此节点List_remove(lList, nNode);Node_delete(nNode);printf("%s\n", "此学生记录已删除。");return;}}printf("%s\n", "没有此学生的记录,请重新输入:");}}// 修改记录void modRec(List* lList){int i, iId = 0;int iSize;Node* nNode = NULL;// 先查询有没有此学生信息for(; ;){printf("%s\n", "请输入学号,如果要退出修改,请输入 0:");scanf("%d", &iId);// 如果输入的是 0 退出函数if(iId == 0)return;// 获取链表中节点总数iSize = lList->iSize;// 获取顶部节点指针nNode = lList->nTop;for(i=0; i<iSize; i++){nNode = nNode->nDown;if(nNode->iId == iId)break;}if(nNode->iId == iId)break;elseprintf("%s\n", "没有此学生的记录,请重新输入:");}// 修改此学生信息char acClass[32], acName[32];float fMath = 0.0, fEng = 0.0, fCmp = 0.0;for(; ;){int iMenu = menu("**************************************************************************\n1------修改姓名 2------修改班级 3------修改数学成绩 4------修改英语成绩 5------修改计算机成绩 6------退出修改\n**************************************************************************\n请输入选项所对应的数字:\n");switch (iMenu){case 1:printf("%s\n", "请输入姓名:");scanf("%s", &acName);iSize = strlen(acName);free(nNode->pcName);nNode->pcName = (char*)malloc(sizeof(char)*(iSize) + 1);strcpy(nNode->pcName, acName);nNode->pcName[iSize] = '\0';break;case 2:printf("%s\n", "请输入班级:");scanf("%s", &acClass);iSize = strlen(acClass);free(nNode->pcClass);nNode->pcClass = (char*)malloc(sizeof(char)*(iSize) + 1);strcpy(nNode->pcClass, acClass);nNode->pcClass[iSize] = '\0';break;case 3:printf("%s\n", "请输入数学成绩:");scanf("%f", &fMath);nNode->fMath = fMath;nNode->fAver = (nNode->fMath + nNode->fEng + nNode->fCmp)/3.0;break;case 4:printf("%s\n", "请输入英语成绩:");scanf("%f", &fEng);nNode->fEng = fEng;nNode->fAver = (nNode->fMath + nNode->fEng + nNode->fCmp)/3.0;break;case 5:printf("%s\n", "请输入计算机成绩:");scanf("%f", &fCmp);nNode->fCmp = fCmp;nNode->fAver = (nNode->fMath + nNode->fEng + nNode->fCmp)/3.0;break;case 6:return;default:printf("%s\n", "您输入的选项不存在,请重新输入。");}}}// 分析记录void analRec(List* lList, float fPassLine){float fMathAver = 0.0, fEngAver = 0.0, fCmpAver = 0.0,/*各科平均分*/fMathMax = 0.0, fEngMax = 0.0, fCmpMax = 0.0,/*各科最高分*/fMathMin = 1000.0, fEngMin = 1000.0, fCmpMin = 1000.0,/*各科最低分*/fMathPassRate = 0.0, fEngPassRate = 0.0, fCmpPassRate = 0.0;/*各科及格率*/int i, iSize = lList->iSize;// 得到顶部节点指针Node* nNode = lList->nTop;for(i=0; i<iSize; i++){nNode = nNode->nDown;// 各科平均分fMathAver = (fMathAver*i + nNode->fMath)/(i + 1);fEngAver = (fEngAver*i + nNode->fEng)/(i + 1);fCmpAver = (fCmpAver*i + nNode->fCmp)/(i + 1);// 各科最高分if(nNode->fMath > fMathMax) fMathMax = nNode->fMath;if(nNode->fEng > fEngMax) fEngMax = nNode->fEng;if(nNode->fCmp > fCmpMax) fCmpMax = nNode->fCmp;// 各科最低分if(nNode->fMath < fMathMin) fMathMin = nNode->fMath;if(nNode->fEng < fEngMin) fEngMin = nNode->fEng;if(nNode->fCmp < fCmpMin) fCmpMin = nNode->fCmp;// 各科及格率fMathPassRate = (nNode->fMath >= fPassLine) ? ((fMathPassRate*i + 1.0)/(i + 1)) : (fMathPassRate*i/(i + 1));fEngPassRate = (nNode->fEng >= fPassLine) ? ((fEngPassRate*i + 1.0)/(i + 1)) : (fEngPassRate*i/(i + 1));fCmpPassRate = (nNode->fCmp >= fPassLine) ? ((fCmpPassRate*i + 1.0)/(i + 1)) : (fCmpPassRate*i/(i + 1));}printf("数学平均分:%.4f\t最高分:%.1f\t最低分:%.1f\t及格率:%.2f", fMathAver, fMathMax, fMathMin, fMathPassRate*100.0);printf("%s", "%\n");printf("英语平均分:%.4f\t最高分:%.1f\t最低分:%.1f\t及格率:%.2f", fEngAver, fEngMax, fEngMin, fEngPassRate*100.0);printf("%s", "%\n");printf("计算机平均分:%.4f\t最高分:%.1f\t最低分:%.1f\t及格率:%.2f", fCmpAver, fCmpMax, fCmpMin, fCmpPassRate*100.0);printf("%s", "%\n");}// 输出记录void oputRec(List* lList){// 得到顶部节点指针Node* nNode = lList->nTop;int i, iSize = lList->iSize;if(iSize <= 0)printf("%s\n", "没有任何学生成绩信息,请重新选择。");elseprintf("%s\n", "以下是学生成绩信息表:");for(i=0; i<iSize; i++){nNode = nNode->nDown;// 输出学号printf("学号:%d\t", nNode->iId);// 输出班级printf("班级:%s\t", nNode->pcClass);// 输出姓名printf("姓名:%s\t", nNode->pcName);// 输出数学成绩printf("数学:%.1f\t", nNode->fMath);// 输出英语成绩printf("英语:%.1f\t", nNode->fEng);// 输出计算机成绩printf("计算机:%.1f\t", nNode->fCmp);// 输出平均成绩printf("平均分:%.2f\n", nNode->fAver);}}

main.c

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include"list.h"#include"oper.h"int main(void){// 创建链表List* lList = List_new();int iMenu = 0;for(; ;){iMenu = menu("**************************************************************************\n\1------添加记录 2------查询记录 3------排序记录 4------删除记录\n\5------修改记录 6------分析记录 7------输出记录 8------退出系统\n\**************************************************************************\n\请输入选项所对应的数字:\n");switch (iMenu){case 1:// 添加记录addRec(lList);break;case 2:// 查询记录srchRec(lList);break;case 3:// 排序记录sortRec(lList);break;case 4:// 删除记录delRec(lList);break;case 5:// 修改记录modRec(lList);break;case 6:// 分析记录 60.0 是及格线analRec(lList, 60.0);break;case 7:// 输出记录oputRec(lList);break;case 8:// 删除链表List_delete(lList);// 退出系统return 0;default:printf("%s\n", "您输入的选项不存在,请重新输入。");}}// 删除链表List_delete(lList);return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。