C語(yǔ)言鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
本文實(shí)例為大家分享了C語(yǔ)言基于鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
一、課程設(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ù)來(lái)實(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;?? ??? ??? ?//語(yǔ)文
?? ?int math;?? ??? ??? ??? ?//數(shù)學(xué)
?? ?int english;?? ??? ??? ?//英語(yǔ)
?? ?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è)無(wú)限循環(huán)里面套一個(gè)switch來(lái)實(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è)無(wú)限循環(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是無(wú)效的數(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)輸入語(yǔ)文成績(jī):");
?? ?scanf("%d", &s->stu.chinese);
?? ?printf("請(qǐng)輸入數(shù)學(xué)成績(jī):");
?? ?scanf("%d", &s->stu.math);
?? ?printf("請(qǐng)輸入英語(yǔ)成績(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語(yǔ)文\t\t數(shù)學(xué)\t\t英語(yǔ)\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語(yǔ)文\t\t數(shù)學(xué)\t\t英語(yǔ)\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)輸入語(yǔ)文成績(jī):");
?? ??? ??? ?scanf("%d", &p->stu.chinese);
?? ??? ??? ?printf("請(qǐng)輸入數(shù)學(xué)成績(jī):");
?? ??? ??? ?scanf("%d", &p->stu.math);
?? ??? ??? ?printf("請(qǐng)輸入英語(yǔ)成績(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ù)為count
?? ?for (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)閉程序

上次輸入的信息還在,說(shuō)明信息保存成功

五、注意事項(xiàng)
文件得和源碼在同一目錄
文件名是"學(xué)生成績(jī).txt"
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- C語(yǔ)言編寫學(xué)生成績(jī)管理系統(tǒng)
- 學(xué)生成績(jī)管理系統(tǒng)C語(yǔ)言代碼實(shí)現(xiàn)
- C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
- C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)源代碼
- C語(yǔ)言實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)實(shí)戰(zhàn)教學(xué)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng)
- C語(yǔ)言結(jié)構(gòu)體版學(xué)生成績(jī)管理系統(tǒng)
- 使用C語(yǔ)言實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
- C語(yǔ)言實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
- C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)課程設(shè)計(jì)
相關(guān)文章
完全掌握C++編程中構(gòu)造函數(shù)使用的超級(jí)學(xué)習(xí)教程
這篇文章主要介紹了C++中的構(gòu)造函數(shù),包括C++11標(biāo)準(zhǔn)中的新特性的介紹,十分推薦!需要的朋友可以參考下2016-01-01
一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié)
這篇文章主要介紹了一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié),這里羅列了Java和C語(yǔ)言和C++以及PHP的實(shí)現(xiàn)需要的朋友可以參考下2015-08-08
Matlab實(shí)現(xiàn)灰色預(yù)測(cè)的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Matlab實(shí)現(xiàn)灰色預(yù)測(cè),文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2022-05-05
C++ 實(shí)現(xiàn)PE文件特征碼識(shí)別的步驟
PE文件就是我們常說(shuō)的EXE可執(zhí)行文件,針對(duì)文件特征的識(shí)別可以清晰的知道該程序是使用何種編程語(yǔ)言實(shí)現(xiàn)的,前提是要有特征庫(kù),PE特征識(shí)別有多種形式,第一種是靜態(tài)識(shí)別,第二種則是動(dòng)態(tài)識(shí)別,我們經(jīng)常使用的PEID查殼工具是基于靜態(tài)檢測(cè)的方法。2021-06-06
Qt圖片繪圖類之QPixmap/QImage/QPicture詳解
這篇文章主要為大家詳細(xì)介紹了Qt圖片繪圖類中QPixmap、QImage和QPicture的使用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03
typedef和#define用法區(qū)別總結(jié)
在C還是C++代碼中,typedef都使用的很多,在C代碼中尤其多,typedef與#define有些相似,其實(shí)是不同的,特別是在一些復(fù)雜的用法上,下面這篇文章主要給大家介紹了關(guān)于typedef和#define用法區(qū)別總結(jié)的相關(guān)資料,需要的朋友可以參考下2023-06-06
C語(yǔ)言中關(guān)于庫(kù)函數(shù) qsort 快排的用法
快速排序Qsort是所有學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)最基礎(chǔ)的一個(gè)部分,也是考試題和面試的一個(gè)小重點(diǎn)。本片文章帶你了解Qsort的詳細(xì)用法規(guī)則2021-09-09
C語(yǔ)言實(shí)現(xiàn)手寫字符串處理工具的示例代碼
這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)手寫字符串處理工具的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-09-09

