C/C++|轻松学做C语言课程设计(学生成绩管理系统-链表实现)

题外话 C语言课程设计,对于初学者来说,主要是综合运用C语言基础知识,以实际项目的形式锻炼编程能力。从今天开始,一起轻松学做C语言课程设计常见项目,建议先运行代码,再一步步理解其实现。
备注:
1.不同C编译器,对C语言程序编译有差别,建议大家选择相同的编译器。
2.代码手机不方便看,可以收藏使用电脑查看,注意各种标点符号。
功能要求 学生成绩管理系统常用功能一般包括:
1.学生信息包括学号、姓名、4门课成绩(语文、数学、英语、专业课),成绩百分制整数;
2.学生信息以文件形式保存;
3.可以显示所有学生信息;
4.按照姓名或学号查询显示学生信息,姓名和学号都唯一不重复;
5.按照学号删除某个学生信息;
6.按照学号修改某个学生信息;
7.计算总分和平均分,按照学生总分或平均分从高到低排序。
实现要点

  • 使用链表保存学生信息,实现增删改查和排序功能;
  • 使用文件保存学生信息;
  • 总分和平均分是根据输入由程序计算得出,不需要手工输入;
  • 难点:使用简单选择排序算法实现链表排序。
备注:简单选择排序算法,是每次循环选出最大值或最小值,交换到链表前面。
编程环境
  • 采用Dev-C++集成开发环境;
  • 涉及C语言知识点:结构、链表、函数、文件读写;
  • 功能点较多,总共600行左右,很大一部分代码是错误处理,因此对于初学者可以将这部分代码精简,预计也就是200-300行左右,下一篇将提供精简版。
# 运行结果*************欢迎使用学生成绩管理系统************* *1:录入成绩2:删除成绩* *3:查询成绩4:修改成绩* *5:成绩排序6:显示所有* *7:保存成绩8:显示菜单* *0:退出系统* *************************************************请输出0-8,回车结束! 1 请您按提示依次输入图书信息(以空格分隔): 学号姓名语文数学英语专业课 202001张三100889789 学生【202001张三】的信息添加成功!请输出0-8,回车结束! 1 请您按提示依次输入图书信息(以空格分隔): 学号姓名语文数学英语专业课 202002李四100100100100 学生【202002李四】的信息添加成功!请输出0-8,回车结束! 6 学号姓名语文数学英语专业课总分平均分 202001张三10088978937493.50 202002李四100100100100400100.00 当前系统总共有2条学生成绩记录!请输出0-8,回车结束! 5 请选择排序方式:1.总分从高到低排序2.平均分从低到高排序 1 学号姓名语文数学英语专业课总分平均分 202002李四100100100100400100.00 202001张三10088978937493.50请输出0-8,回车结束! 3 请选择查询方式:1.学号查询2.姓名查询 202002 请输入学生姓名:张三 学号姓名语文数学英语专业课总分平均分 202001张三10088978937493.50请输出0-8,回车结束! 4 请输入要修改的学生学号:202002 学号202002对应的学生信息如下: 学号姓名语文数学英语专业课总分平均分 202002李四100100100100400100.00 请依次输入修改后信息,不变的信息请同样输入: 姓名语文数学英语专业课 李四9910099100 修改成功,修改后信息如下: 学号姓名语文数学英语专业课总分平均分 202002李四991009910039899.50请输出0-8,回车结束! 6 学号姓名语文数学英语专业课总分平均分 202002李四991009910039899.50 202001张三10088978937493.50 当前系统总共有2条学生成绩记录!请输出0-8,回车结束! 0 ByeBye....~~

其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。
源代码
/* #include #include #include #define HEAD_INFO"学号\t姓名\t语文\t数学\t英语\t专业课\t总分\t平均分\n" #define HEAD_INFO2 "学号\t姓名\t语文\t数学\t英语\t专业课\n" // 定义学生信息数据结构 struct student{ // 学号 intnum; // 姓名 charname[20]; // 语文 intchinese; // 数学 intmath; // 英语 intenglish; // 专业课 intprofession; // 总分 inttotal; // 平均分 doubleaverage; }; // 定义链表结点结构类型 struct node { struct studentstu; struct node*next; }; /* 定义各种功能函数 */ // 显示功能菜单 void showMenu(); // 录入信息 void addStudent(struct node *head); // 删除信息 void deleteStudent(struct node *head); // 查询信息 void queryStudent(struct node *head); // 修改信息 void modifyStudent(struct node *head); // 成绩排序 void sortStudent(struct node *head); // 显示所有 void showStudent(struct node *head); // 保存信息 void saveStudent(struct node *head); // 退出 void exitProgram(struct node *head); // 定义链表基本操作函数 struct node *createStudentNode(struct student *stu); struct node *insertStudentNode(struct node *head, struct student *stu); struct node *createStudentList(); voidfreeStudentList(struct node* head); struct node *queryStudentListByNum(struct node* head, int num); struct node *queryStudentListByName(struct node* head, char *name); intdeleteStudentListByNum(struct node* head, int num); intgetStudentListLength(struct node* head); struct node *sortStudentListByTotal(struct node *head); struct node *sortStudentListByAverage(struct node *head); voidprintStudentListInfo(struct node* head); voidsaveStudentListToFile(struct node* head); voiderror(const char* err); int main() { // 创建学生成绩空链表保存信息 struct node* list = createStudentList(); // 显示功能主菜单 showMenu(); char a[10]; while (1) { printf("\n请输出0-8,回车结束!\n"); if (fgets(a, 10, stdin) != NULL) { switch (a[0]) { case '0': exitProgram(list); break; case '1': addStudent(list); break; case '2': deleteStudent(list); break; case '3': queryStudent(list); break; case '4': modifyStudent(list); break; case '5': sortStudent(list); break; case '6': showStudent(list); break; case '7': saveStudent(list); break; case '8': showMenu(); break; default: printf("请重新输入正确的功能数字0-8!\n"); } } } return 0; } // 创建学生成绩结点 struct node *createStudentNode(struct student *stu) { struct node* p = (struct node*)calloc(1,sizeof(struct node)); if(stu != NULL) { struct student *s = &(p->stu); if(p != NULL) { s->num = stu->num; strcpy(s->name, stu->name); s->chinese = stu->chinese; s->math = stu->math; s->english = stu->english; s->profession = stu->profession; // 计算成绩 s->total = s->chinese + s->math + \ s->english + s->profession; s->average = s->total*1.0/4; p->next = NULL; } } return p; } // 表尾增加学生成绩 struct node *insertStudentNode(struct node *head, struct student *stu) { struct node *node = NULL; if(head != NULL) { node =createStudentNode(stu); struct student *s = &(node->stu); if(node != NULL) { struct node* p = head; // 循环找到链表最后的结点 while(p->next != NULL) p = p->next; p->next = node; } } return node; } // 创建带头结点的学生成绩空链表 struct node *createStudentList() { // 创建头结点 return createStudentNode(NULL); } // 释放学生成绩链表内存空间 void freeStudentList(struct node* head) { struct node* p = head; while(p != NULL) { head = p->next; free(p); p = head; } } // 根据学号查找学生成绩 struct node *queryStudentListByNum(struct node* head, int num) {struct node *p = NULL; if(head != NULL) { p = head->next; while(p != NULL) { if(p->stu.num == num) break; p = p->next; } } return p; } // 根据姓名查找学生成绩 struct node *queryStudentListByName(struct node* head, char *name) {struct node *p = NULL; if(head != NULL) { p = head->next; while(p != NULL) { if(strcmp(p->stu.name, name) == 0) break; p = p->next; } } return p; } // 根据学号删除学生成绩 int deleteStudentListByNum(struct node* head, int num) { // p保存当前结点,pre保存前一个结点 struct node *p = NULL, *pre = NULL; // 返回结果0或1 int status = 0; if(head != NULL) { pre = head; p = head->next; while(p != NULL) { if(p->stu.num == num) { pre->next = p->next; free(p); status = 1; break; } pre = p; p = p->next; } } return status; } // 获取学生成绩链表的长度 int getStudentListLength(struct node* head) { int n = 0; struct node *p = NULL; if(head != NULL) { p = head->next; while(p != NULL) { n++; p = p->next; } } return n; } // 按总分从高到低排序学生成绩 struct node *sortStudentListByTotal(struct node *head) { if(head != NULL) { struct node *p1, *p2, *max; struct student s; p1 = head; // 简单选择排序 // 直接交换信息,不改变结点 while((p1=p1->next) != NULL) { max = p1; p2 = p1; while((p2=p2->next) != NULL) { if((p2->stu).total > (max->stu).total) max = p2; }if(max != p1) { s = p1->stu; p1->stu = max->stu; max->stu = s; } } } return head; } // 按平均分从小到大排序学生成绩 struct node *sortStudentListByAverage(struct node *head) { if(head != NULL) { struct node *p1, *p2, *min; struct student s; p1 = head; // 简单选择排序 // 直接交换信息,不改变结点 while((p1=p1->next) != NULL) { min = p1; p2 = p1; while((p2=p2->next) != NULL) { if((p2->stu).average < (min->stu).average) min = p2; }if(min != p1) { s = p1->stu; p1->stu = min->stu; min->stu = s; } } } return head; }// 打印出链表所有结点保存的图书信息 void printStudentListInfo(struct node* head) { struct node* p = head->next; printf(HEAD_INFO); struct student *s; while(p != NULL) { s = &(p->stu); printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession, \ s->total, s->average); p = p->next; } }// 文件保存学生成绩链表所有信息 void saveStudentListToFile(struct node* head) { if(head != NULL) { struct node *p = head->next; FILE* fp = fopen("students.txt", "w+"); if(fp != NULL) { struct student *s; while(p != NULL) { s = &(p->stu); fprintf(fp,"%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession,\ s->total, s->average); p = p->next; } fclose(fp); }else { error("打开students文件失败,请检查!\n"); } } } // 屏幕显示各类出错信息,并退出程序 void error(const char* err) { printf(err); exit(-1); } void showMenu() {printf("\t*************欢迎使用学生成绩管理系统*************\t\n"); printf("\t*1:录入成绩2:删除成绩*\t\n"); printf("\t*3:查询成绩4:修改成绩*\t\n"); printf("\t*5:成绩排序6:显示所有*\t\n"); printf("\t*7:保存成绩8:显示菜单*\t\n"); printf("\t*0:退出系统*\t\n"); printf("\t**************************************************\t\n"); } // 录入信息 void addStudent(struct node *head) { printf("请您按提示依次输入图书信息(以空格分隔):\n"); printf(HEAD_INFO2); char a[1024]; struct student stu; if (fgets(a, 1024, stdin) != NULL &&\ sscanf(a, "%d%s%d%d%d%d", &stu.num, \ stu.name, &stu.chinese, &stu.math,\ &stu.english, &stu.profession) >= 6) { if (queryStudentListByNum(head, stu.num) != NULL) printf("该学生成绩信息已经存在,无法增加!\n"); else { insertStudentNode(head, &stu); printf("学生【%d\t%s】的信息添加成功!\n", stu.num, stu.name); } } else { printf("输入格式有误,请重新输入!\n"); } } // 删除信息 void deleteStudent(struct node *head) { printf("请输入要删除的学生学号:"); char a[1024]; int num; if (fgets(a, 1024, stdin) != NULL && \ sscanf(a, "%d", &num) != EOF) { if (deleteStudentListByNum(head, num)) { printf("学号%d对应的学生信息删除成功!\n", num); }else { printf("学号%d对应的学生信息不存在!\n", num); } } else { printf("输入格式有误,请重新输入!\n"); } } // 查询信息 void queryStudent(struct node *head) { printf("请选择查询方式:1.学号查询2.姓名查询 \n"); char a[1024]; if (fgets(a, 1024, stdin) != NULL) { if(a[0] == '1') { printf("请输入学生学号:"); int num; if (fgets(a, 1024, stdin) != NULL && \ sscanf(a, "%d", &num) != EOF) { struct node *p = queryStudentListByNum(head, num); if(p == NULL) { printf("未查到学号%d对应的学生信息!\n", num); }else { struct student *s = &(p->stu); printf(HEAD_INFO); printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession, \ s->total, s->average); } }else { printf("输入格式有误,请重新输入!\n"); }}else if(a[0] == '2') { printf("请输入学生姓名:"); charname[20]; if (fgets(a, 1024, stdin) != NULL && \ sscanf(a, "%s", name) != EOF) { struct node *p = queryStudentListByName(head, name); if(p == NULL) { printf("未查到姓名%s对应的学生信息!\n", name); }else { struct student *s = &(p->stu); printf(HEAD_INFO); printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession, \ s->total, s->average); } }else { printf("输入格式有误,请重新输入!\n"); }}else { printf("输入格式有误,请重新输入!\n"); } } } // 修改信息 void modifyStudent(struct node *head) { printf("请输入要修改的学生学号:"); char a[1024]; int num; if (fgets(a, 1024, stdin) != NULL &&\ sscanf(a, "%d", &num) != EOF) { struct node *p = queryStudentListByNum(head, num); if (p == NULL) { printf("学号%d对应的学生信息不存在!\n", num); }else { struct student *s = &(p->stu); printf("学号%d对应的学生信息如下:\n", num); printf(HEAD_INFO); printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession, \ s->total, s->average); printf("请依次输入修改后信息,不变的信息请同样输入:\n"); printf("姓名\t语文\t数学\t英语\t专业课\n"); struct student stu; if (fgets(a, 1024, stdin) != NULL &&\ sscanf(a, "%s%d%d%d%d", stu.name, &stu.chinese, \ &stu.math, &stu.english, &stu.profession) >= 5) { strcpy(s->name, stu.name); s->chinese = stu.chinese; s->math = stu.math; s->english = stu.english; s->profession = stu.profession; // 计算成绩 s->total = stu.chinese + stu.math + \ stu.english + stu.profession; s->average = s->total*1.0/4; printf("修改成功,修改后信息如下:\n"); printf(HEAD_INFO); printf("%d\t%s\t%d\t%d\t%d\t%d\t%d\t%.2lf\n", s->num, s->name, \ s->chinese, s->math, s->english, s->profession, \ s->total, s->average); }else { printf("输入格式有误,请重新输入!\n"); } } }else { printf("输入格式有误,请重新输入!\n"); } } // 成绩排序 void sortStudent(struct node *head) { printf("请选择排序方式:1.总分从高到低排序2.平均分从低到高排序 \n"); char a[1024]; if (fgets(a, 1024, stdin) != NULL) { if(a[0] == '1') { sortStudentListByTotal(head); printStudentListInfo(head); }else if(a[0] == '2') { sortStudentListByAverage(head); printStudentListInfo(head); }else { printf("输入格式有误,请重新输入!\n"); } }else { printf("输入格式有误,请重新输入!\n"); } } // 显示所有 void showStudent(struct node *head) { printStudentListInfo(head); printf("当前系统总共有%d条学生成绩记录!\n", getStudentListLength(head)); } // 保存信息 void saveStudent(struct node *head) { saveStudentListToFile(head); printf("保存成功,信息存放在students.txt文件!\n"); } // 退出 void exitProgram(struct node *head) { freeStudentList(head); printf("ByeBye....~~\n"); exit(0); }

【C/C++|轻松学做C语言课程设计(学生成绩管理系统-链表实现)】其实做为一个学习者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个C/C++基础交流583650410,不管你是小白还是转行人士欢迎入驻,大家一起交流成长。
C/C++|轻松学做C语言课程设计(学生成绩管理系统-链表实现)
文章图片

C/C++|轻松学做C语言课程设计(学生成绩管理系统-链表实现)
文章图片

    推荐阅读