【原创】单链表实战学生成绩管理系统
问题背景:
通过单链表实战学生成绩管理系统,涉及到的知识点比较广泛(仅关注原理、业务逻辑校验细节未关注):
单链表自身、结构体、指针、位操作、趣味宏、堆内存、排序算法等等。
先看效果图:
实现代码:
/* * ===================================================================================== * * Filename: student.c * * Description: 大学生成绩管理系统 * * Version: 1.0 * Created: 2021年01月08日 23时04分42秒 * Revision: none * Compiler: gcc * * Author: blogdaren * Organization: www.phpcreeper.com * * ===================================================================================== */ #include <stdio.h> #include <stdlib.h> #include "./myinclude/global.h" //以下宏以及各种声明在标准化编程时应当移植到独立的student.h头文件 #define SUCCESS 0 #define FAILURE 1 #define LIST_FLAG_INITIALIZED (1<<0) #define MAX_NUMBER_OF_SPECIAL_CHAR 58 #define DO_WHILE_START do{ #define DO_WHILE_END }while(8 != command); #define GET_AVG_SCORE(x1, x2, x3) ((x1) + (x2) + (x3)) / 3 #define COPY_DATA(p1, p2) \ do \ { \ strcpy((p1)->data.name, (p2)->name); \ (p1)->data.yuwen_score = (p2)->yuwen_score; \ (p1)->data.shuxue_score = (p2)->shuxue_score; \ (p1)->data.yingyu_score = (p2)->yingyu_score; \ (p1)->data.avg_score = GET_AVG_SCORE( \ (p2)->yuwen_score, \ (p2)->shuxue_score, \ (p2)->yingyu_score \ ); \ }while(0); \ struct student { char name[20]; float yuwen_score; float shuxue_score; float yingyu_score; float avg_score; }; typedef struct student Item; typedef struct node { Item data; struct node *next; }Node; typedef struct list { Node *head; int total; int flags; }List; void showWelcome(); void showTableTitle(); Node *createNode(List *plist, Item *pitem); Node *deleteNode(List *plist, char *name); Node *modifyNode(List *plist, char *name); void freeNode(List *plist); void showListData(List *plist); void initListData(List *plist); int countListData(List *plist); Node *searchListData(List *plist, char *name); void sortListData(List *plist); void showSortedListData(List *plist); int main() { int result, i, command; char tname[20]; Node *tmp; List mylist, *plist; Item item, *pitem; plist = &mylist; pitem = &item; showWelcome(); initListData(plist); i = 0; DO_WHILE_START printf("\n--> 请输入一个有效数字指令:"); result = scanf("%d", &command); /*printf("%d-%d\n", result, command);*/ if(result != 1) scanf("%*[^\n]"); if(command < 1 || command > 8) continue; switch(command) { case 1: showWelcome(); break; case 2: i++; printf("请输入第(%02d)个学生的真实姓名:", i); scanf("%s", item.name); printf("请输入第(%02d)个学生的语文成绩:", i); scanf("%f", &item.yuwen_score); printf("请输入第(%02d)个学生的数学成绩:", i); scanf("%f", &item.shuxue_score); printf("请输入第(%02d)个学生的英语成绩:", i); scanf("%f", &item.yingyu_score); createNode(plist, pitem); break; case 3: printf("--> 请输入待删除成绩的学生姓名:"); scanf("%s", tname); tmp = deleteNode(plist, tname); if(NULL == tmp) printf("<-- 没有找到要删除的记录!!!"); else printf("<-- 嘿嘿记录已经成功删除!!!"); break; case 4: printf("--> 请输入待修改成绩的学生姓名:"); scanf("%s", tname); tmp = modifyNode(plist, tname); break; case 5: showListData(plist); break; case 6: showSortedListData(plist); break; case 7: system("clear"); break; case 8: freeNode(plist); printf("<-- Bye!! See You Next Time!!\n"); break; default: break; } DO_WHILE_END return 0; } void initListData(List *plist) { if(plist->flags & LIST_FLAG_INITIALIZED) return; plist->head = NULL; plist->total = 0; plist->flags |= LIST_FLAG_INITIALIZED; } int countListData(List *plist) { return plist->total; } Node *createNode(List *plist, Item *pitem) { Node *pnode, *pnew; if(countListData(plist) == 0) { plist->head = pnode = (Node *)malloc(sizeof(Node)); if(pnode == NULL) { printf("malloc failed\n"); exit(FAILURE); } plist->total++; COPY_DATA(pnode, pitem); pnode->next = NULL; return pnode; } pnode = plist->head; while(pnode->next != NULL) { pnode = pnode->next; } pnew = (Node *)malloc(sizeof(Node)); COPY_DATA(pnew, pitem); pnew->next = NULL; pnode->next = pnew; plist->total++; return pnode; } void showListData(List *plist) { Node *pnode; if(countListData(plist) == 0) { printf("<-- 列表中空空如也!!!"); return; } pnode = plist->head; showTableTitle(); while(pnode != NULL) { printf("‖ %-11s‖ %-9.2f‖ %-9.2f‖ %-9.2f‖ %-9.2f‖\n", pnode->data.name, pnode->data.yuwen_score, pnode->data.shuxue_score, pnode->data.yingyu_score, pnode->data.avg_score ); echoRepeatString("=", MAX_NUMBER_OF_SPECIAL_CHAR); pnode = pnode->next; } printf("‖ 总共 %d 条记录 ‖\n", countListData(plist)); echoRepeatString("=", MAX_NUMBER_OF_SPECIAL_CHAR); } void freeNode(List *plist) { Node *pnode; pnode = plist->head; while(pnode != NULL) { free(pnode); printf("<-- 成功释放节点 (%p)\n", pnode); pnode = pnode->next; } plist->head = NULL; plist->total = 0; } Node *deleteNode(List *plist, char *name) { Node *phead, *pnode, *tmp = NULL; phead = pnode = plist->head; tmp = searchListData(plist, name); if(NULL == tmp) return NULL; //如果删除的是头指针 if(phead == tmp) { plist->head = tmp->next; free(tmp); plist->total--; return phead; } //否则删除的必定是后续某个指针 while(pnode->next != tmp) { pnode = pnode->next; } pnode->next = tmp->next; free(tmp); plist->total--; return tmp; } Node *modifyNode(List *plist, char *name) { Node *tmp = NULL; Item item2, *pitem2; pitem2 = &item2; tmp = searchListData(plist, name); if(NULL == tmp) return NULL; strcpy(item2.name, name); printf("请输入该学生修正后的语文成绩:"); scanf("%f", &item2.yuwen_score); printf("请输入该学生修正后的数学成绩:"); scanf("%f", &item2.shuxue_score); printf("请输入该学生修正后的英语成绩:"); scanf("%f", &item2.yingyu_score); COPY_DATA(tmp, pitem2); } Node *searchListData(List *plist, char *name) { Node *pnode; if(countListData(plist) == 0) return NULL; pnode = plist->head; while(pnode != NULL) { if(strcmp(pnode->data.name, name) == 0) { return pnode; } pnode = pnode->next; } return NULL; } void showWelcome() { putchar('\n'); puts("============================================"); puts("‖ 单链表实战学生成绩管理系统,指令如下: ‖"); puts("============================================"); puts("‖ 1. 显示帮助界面 ‖"); puts("‖ 2. 新增一条学生成绩 ‖"); puts("‖ 3. 根据姓名删除学生成绩 ‖"); puts("‖ 4. 根据姓名修改学生成绩 ‖"); puts("‖ 5. 查看班级所有学生成绩 ‖"); puts("‖ 6. 按照平均成绩降序展示 ‖"); puts("‖ 7. 清理当前屏幕 ‖"); puts("‖ 8. 退出当前程序 ‖"); puts("============================================"); } void showTableTitle() { echoRepeatString("=", MAX_NUMBER_OF_SPECIAL_CHAR); printf( "‖ %s ‖ %s ‖ %s ‖ %s ‖ %s", "学生姓名", "语文成绩", "数学成绩", "英语成绩", "平均成绩 ‖\n" ); echoRepeatString("=", MAX_NUMBER_OF_SPECIAL_CHAR); } void sortListData(List *plist) { int i, total; Node *current, *after; Item tmpdata; total = countListData(plist); if(total <= 0) return; while(total > 0) { current = plist->head; after = current->next; for(i = 0; i < total; i++) { if(after == NULL) break; if(current->data.avg_score < after->data.avg_score) { strcpy(tmpdata.name, after->data.name); tmpdata.yuwen_score = after->data.yuwen_score; tmpdata.shuxue_score = after->data.shuxue_score; tmpdata.yingyu_score = after->data.yingyu_score; tmpdata.avg_score = after->data.avg_score; strcpy(after->data.name, current->data.name); after->data.yuwen_score = current->data.yuwen_score; after->data.shuxue_score = current->data.shuxue_score; after->data.yingyu_score = current->data.yingyu_score; after->data.avg_score = current->data.avg_score; strcpy(current->data.name, tmpdata.name); current->data.yuwen_score = tmpdata.yuwen_score; current->data.shuxue_score = tmpdata.shuxue_score; current->data.yingyu_score = tmpdata.yingyu_score; current->data.avg_score = tmpdata.avg_score; } current = after; after = current->next; } total--; } printf("<-- 操作成功,按照平均成绩由高到低排列如下:\n"); } void showSortedListData(List *plist) { sortListData(plist); showListData(plist); }
版权声明:除非注明,本文由( blogdaren )原创,转载请保留文章出处。
本文链接:【原创】单链表实战学生成绩管理系统
发表评论: