学生成绩管理系统(C语言链表)
?一、課程設(shè)計(jì)題目及內(nèi)容
程序名稱:學(xué)生成績(jī)管理系統(tǒng)
功能要求:錄入學(xué)生成績(jī),修改學(xué)生成績(jī),統(tǒng)計(jì)每個(gè)學(xué)生的總分及平均分并能根據(jù)學(xué)生的平均成績(jī)排序,查詢學(xué)生成績(jī),輸出學(xué)生成績(jī)單。能夠保存學(xué)生成績(jī),實(shí)現(xiàn)文件的讀寫。界面簡(jiǎn)潔大方,易操作。
?二、主要設(shè)計(jì)思路
以鏈表作為數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)學(xué)生成績(jī)等信息,然后圍繞鏈表編寫一堆函數(shù)來實(shí)現(xiàn)一堆功能
程序開始時(shí)會(huì)讀取文件數(shù)據(jù)到鏈表,結(jié)束時(shí)會(huì)把更新后的鏈表中的信息重新寫入到文件中,以實(shí)現(xiàn)數(shù)據(jù)的保存
?三、程序源碼及具體注釋
?(1)預(yù)處理指令
導(dǎo)入<stdlib.h>是因?yàn)闀?huì)用到malloc函數(shù)和free函數(shù)
導(dǎo)入<string.h>是因?yàn)闀?huì)用到strcmp函數(shù)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LEN 10 #define FILE_NAME "學(xué)生成績(jī).txt"(2)類型定義
1.student類型定義
一個(gè)student變量代表一組學(xué)生信息
typedef struct {char name[NAME_LEN + 1];//姓名int number; //學(xué)號(hào)int chinese; //語文int math; //數(shù)學(xué)int english; //英語int average; //平均分int sum; //總分 } student; //用于存儲(chǔ)單個(gè)學(xué)生的信息2.?studentNode類型定義
一個(gè)studentNode變量代表一個(gè)學(xué)生節(jié)點(diǎn)
typedef struct node {student stu; //數(shù)據(jù)域,存儲(chǔ)學(xué)生信息struct node *next; //指針域,指向下一個(gè)節(jié)點(diǎn) } studentNode; //學(xué)生節(jié)點(diǎn)3.?studentList類型定義
一個(gè)studentList變量代表一個(gè)學(xué)生鏈表
typedef struct {studentNode *head; //頭指針studentNode *tail; //尾指針int count; //學(xué)生節(jié)點(diǎn)總數(shù) } studentList; //學(xué)生鏈表(3)函數(shù)原型
void initialize(studentList *L);//初始化鏈表,創(chuàng)建頭節(jié)點(diǎn) void enter(studentList *L); //錄入鏈表 void display(studentList *L); //輸出鏈表 void find(studentList *L); //查找某節(jié)點(diǎn) void modify(studentList *L); //修改某節(jié)點(diǎn) void sort(studentList *L); //降序重新建表并輸出 void write(studentList *L); //寫入文件,邊寫邊釋放空間 void read(studentList *L); //讀取文件,邊讀邊建表(4)main函數(shù)定義
開頭會(huì)創(chuàng)建并初始化一個(gè)鏈表,然后把文件的信息讀到鏈表中
通過一個(gè)無限循環(huán)里面套一個(gè)switch來實(shí)現(xiàn)與用戶互動(dòng)
結(jié)尾會(huì)把鏈表中的信息寫到文件中,然后銷毀鏈表
int main() {//互動(dòng)界面printf(" **************學(xué)生成績(jī)管理系統(tǒng)**************\n");printf(" * 1.錄入新的學(xué)生成績(jī) *\n");printf(" * 2.按姓名修改學(xué)生成績(jī) *\n");printf(" * 3.按姓名查詢學(xué)生成績(jī) *\n");printf(" * 4.輸出全部學(xué)生的成績(jī) *\n");printf(" * 5.按平均分輸出學(xué)生成績(jī) *\n");printf(" * 6.退出學(xué)生成績(jī)管理系統(tǒng) *\n");printf(" ********************************************\n");printf(" \n");//創(chuàng)建學(xué)生鏈表studentList *L = (studentList *)malloc(sizeof(studentList));//初始化學(xué)生鏈表initialize(L);//從文件里讀取數(shù)據(jù)到鏈表read(L);//互動(dòng)界面是用一個(gè)無限循環(huán)和一個(gè)switch寫的while (1) {int code;printf("請(qǐng)輸入你想進(jìn)行的操作對(duì)應(yīng)的數(shù)字: ");scanf("%d", &code);switch (code) {case 1:enter(L);break;case 2:modify(L);break;case 3:find(L);break;case 4:display(L);break;case 5:sort(L);break;case 6:write(L);free(L->head); //頭節(jié)點(diǎn)被銷毀free(L); //鏈表被銷毀return 0;default:printf("%d是無效的數(shù)字,請(qǐng)重新輸入!\n\n", code);break;}}return 0; }(5)其他函數(shù)定義?
1.initialize函數(shù)定義
接收一個(gè)鏈表指針作為參數(shù)
創(chuàng)建一個(gè)頭節(jié)點(diǎn),不存儲(chǔ)任何信息,讓鏈表的頭尾指針都指向它
鏈表的初始長(zhǎng)度設(shè)為0
void initialize(studentList *L) {//創(chuàng)建頭節(jié)點(diǎn)studentNode *s = (studentNode *)malloc(sizeof(studentNode));s->next = NULL;//初始化鏈表://頭尾指針均指向頭節(jié)點(diǎn),初始長(zhǎng)度為零L->head = s;L->tail = s;L->count = 0; }2.enter函數(shù)定義
接收一個(gè)鏈表指針作為參數(shù)
讓用戶鍵入信息并存到新節(jié)點(diǎn)中
把新節(jié)點(diǎn)插進(jìn)鏈表中
void enter(studentList *L) {//創(chuàng)建新節(jié)點(diǎn)studentNode *s = (studentNode *)malloc(sizeof(studentNode));//鍵入信息并存到新節(jié)點(diǎn)中printf("請(qǐng)輸入學(xué)生姓名:");scanf("%s", s->stu.name);printf("請(qǐng)輸入學(xué)生學(xué)號(hào):");scanf("%d", &s->stu.number);printf("請(qǐng)輸入語文成績(jī):");scanf("%d", &s->stu.chinese);printf("請(qǐng)輸入數(shù)學(xué)成績(jī):");scanf("%d", &s->stu.math);printf("請(qǐng)輸入英語成績(jī):");scanf("%d", &s->stu.english);s->stu.sum = s->stu.chinese + s->stu.math + s->stu.english;s->stu.average = s->stu.sum / 3;//若鏈表為空,將尾指針指向新節(jié)點(diǎn)if (L->head == L->tail) {L->tail = s;}//將新節(jié)點(diǎn)插進(jìn)鏈表頭部(頭插法)s->next = L->head->next;L->head->next = s;L->count++;//輸出互動(dòng)信息printf("信息錄入成功!\n\n"); }3.display函數(shù)定義
遍歷鏈表輸出就完事兒了
void display(studentList *L) {printf("共有%d組學(xué)生數(shù)據(jù):\n", L->count);printf("姓名\t\t學(xué)號(hào)\t\t語文\t\t數(shù)學(xué)\t\t英語\t\t總分\t\t平均分\n");//創(chuàng)建一節(jié)點(diǎn)指針指向頭節(jié)點(diǎn)studentNode *p;p = L->head;//遍歷鏈表輸出while (p->next) {p = p->next;printf("%s", p->stu.name);printf("\t\t%d", p->stu.number);printf("\t\t%d", p->stu.chinese);printf("\t\t%d", p->stu.math);printf("\t\t%d", p->stu.english);printf("\t\t%d", p->stu.sum);printf("\t\t%d", p->stu.average);printf("\n");}printf("\n"); }?4.find函數(shù)定義
void find(studentList *L) {//讓用戶輸入要查找的學(xué)生printf("請(qǐng)輸入學(xué)生姓名:");char name[NAME_LEN + 1];scanf("%s", name);//遍歷鏈表對(duì)比名字studentNode *p = L->head->next;while (p) {//符合了就輸出并結(jié)束函數(shù)if (strcmp(p->stu.name, name) == 0) {printf("姓名\t\t學(xué)號(hào)\t\t語文\t\t數(shù)學(xué)\t\t英語\t\t總分\t\t平均分\n");printf("%s", p->stu.name);printf("\t\t%d", p->stu.number);printf("\t\t%d", p->stu.chinese);printf("\t\t%d", p->stu.math);printf("\t\t%d", p->stu.english);printf("\t\t%d", p->stu.sum);printf("\t\t%d", p->stu.average);printf("\n\n");return;}//名字不符合就下一個(gè)p = p->next;}//遍歷完里都沒找到這個(gè)名字printf("沒找到這個(gè)%s的信息!\n\n", name); }?5.modify函數(shù)定義?
void modify(studentList *L) {//讓用戶輸入要修改的學(xué)生printf("請(qǐng)輸入學(xué)生姓名:");char name[NAME_LEN + 1];scanf("%s", name);//遍歷鏈表對(duì)比名字studentNode *p = L->head->next;while (p) {//符合了就讓用戶重新鍵入并結(jié)束函數(shù)if (strcmp(p->stu.name, name) == 0) {printf("請(qǐng)重新輸入信息:\n");printf("請(qǐng)輸入學(xué)生學(xué)號(hào):");scanf("%d", &p->stu.number);printf("請(qǐng)輸入語文成績(jī):");scanf("%d", &p->stu.chinese);printf("請(qǐng)輸入數(shù)學(xué)成績(jī):");scanf("%d", &p->stu.math);printf("請(qǐng)輸入英語成績(jī):");scanf("%d", &p->stu.english);p->stu.sum = p->stu.chinese + p->stu.math + p->stu.english;p->stu.average = p->stu.sum / 3;printf("信息修改成功!\n\n");return;}//名字不符合就下一個(gè)p = p->next;}//遍歷完里都沒找到這個(gè)名字printf("沒找到這個(gè)%s的信息!\n\n", name); }6.sort函數(shù)定義
void sort(studentList *L) {//兩個(gè)節(jié)點(diǎn)都沒有排個(gè)屁序if (L->count < 2) {printf("鏈表排序完成!\n");display(L);return;}//插入排序studentNode *p, *pre, *tmp;//p指向第二個(gè)學(xué)生節(jié)點(diǎn)p = L->head->next;//鏈表從頭節(jié)點(diǎn)和第一個(gè)學(xué)生節(jié)點(diǎn)處斷開L->head->next = NULL;//從第一個(gè)學(xué)生節(jié)點(diǎn)開始一直往后循環(huán)while (p) {//存好下一個(gè)節(jié)點(diǎn)的指針tmp = p->next;//找到插入位置pre = L->head;while (pre->next != NULL && pre->next->stu.average > p->stu.average)pre = pre->next;//更新尾指針if (pre->next == NULL) {L->tail = p;}//插入p->next = pre->next;pre->next = p;//跳到下一個(gè)p = tmp;}printf("鏈表排序完成!\n");display(L); }7.write函數(shù)定義
此函數(shù)用于把鏈表中的信息保存到文件中并且銷毀所有節(jié)點(diǎn)(頭節(jié)點(diǎn)除外)
void write(studentList *L) {//打開文件流FILE *fp = fopen(FILE_NAME, "w");if (fp == NULL) {printf("文件%s打開失敗\n", FILE_NAME);exit(EXIT_FAILURE);}//將學(xué)生節(jié)點(diǎn)總數(shù)輸出在第一行fprintf(fp, "%d\n", L->count);//創(chuàng)建一節(jié)點(diǎn)指針指向頭節(jié)點(diǎn)studentNode *p;p = L->head->next;//遍歷鏈表,一組數(shù)據(jù)作為一行輸出while (p) {fprintf(fp, "%s ", p->stu.name);fprintf(fp, "%d ", p->stu.number);fprintf(fp, "%d ", p->stu.chinese);fprintf(fp, "%d ", p->stu.math);fprintf(fp, "%d ", p->stu.english);fprintf(fp, "%d ", p->stu.sum);fprintf(fp, "%d ", p->stu.average);fprintf(fp, "\n");//輸出完成之后釋放節(jié)點(diǎn)空間studentNode *next = p->next;free(p);p = next;}//關(guān)閉文件流fclose(fp);//互動(dòng)信息printf("數(shù)據(jù)已保存!謝謝使用,再見!\n"); }8.read函數(shù)定義
此函數(shù)用于把文件中的信息讀取到鏈表中并且創(chuàng)建節(jié)點(diǎn)(頭節(jié)點(diǎn)除外)
void read(studentList *L) {//打開文件流FILE *fp = fopen(FILE_NAME, "r");if (fp == NULL) {printf("文件%s打開失敗\n", FILE_NAME);exit(EXIT_FAILURE);}//讀取第一行的學(xué)生節(jié)點(diǎn)總數(shù)fscanf(fp, "%d", &L->count);//循環(huán)讀取數(shù)據(jù),循環(huán)次數(shù)為countfor (int i = 1; i <= L->count; i++) {//創(chuàng)建新節(jié)點(diǎn)studentNode *s = (studentNode *)malloc(sizeof(studentNode));//讀取數(shù)據(jù)fscanf(fp, "%s ", s->stu.name);fscanf(fp, "%d ", &s->stu.number);fscanf(fp, "%d ", &s->stu.chinese);fscanf(fp, "%d ", &s->stu.math);fscanf(fp, "%d ", &s->stu.english);fscanf(fp, "%d ", &s->stu.sum);fscanf(fp, "%d ", &s->stu.average);//將新節(jié)點(diǎn)插進(jìn)鏈表尾部(尾插法)s->next = NULL;L->tail->next = s;L->tail = s;}//關(guān)閉文件流fclose(fp); }四、運(yùn)行示例
輸出全部學(xué)生成績(jī)
錄入一組新數(shù)據(jù)然后關(guān)閉程序
?上次輸入的信息還在,說明信息保存成功
五、注意事項(xiàng)?
文件得和源碼在同一目錄
文件名是"學(xué)生成績(jī).txt"
總結(jié)
以上是生活随笔為你收集整理的学生成绩管理系统(C语言链表)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java马士兵
- 下一篇: mc服务器钓鱼系统,钓鱼 - Minec