#include"stdio.h" #include"stdlib.h" #include"string.h" //用於調用一些函數 struct person { char name[20]; int ID; int chinese; int english; int math; struct person *next; //連接處的指針 }; //由於create里面就有initialize所以先把initialize放在前面 void initialize(struct person *p, int num) { //初始化鏈表里面的值 printf("innitialize person %d\n name is:", num); //num用於計入輸入的第幾個同學 scanf_s("%s", &p->name, sizeof(p->name)); getchar(); printf("ID:"); scanf_s("%d", &p->ID); getchar(); printf("chinese:"); scanf_s("%d", &p->chinese); getchar(); printf("math:"); scanf_s("%d", &p->math); getchar(); printf("english:"); scanf_s("%d", &p->english); getchar(); } struct person *create(int len) { int num = 0; struct person *h = 0, *c, *pre = 0; while (num < len) { c = (struct person*)malloc(sizeof(struct person)); //malloc取內存 sizeof為這個內存的大小 然后轉化成指針 if (num == 0) { h = c; pre = c; } // 如果num=0 h存下了首地址 為以后拿做准備 c->next = NULL; if (num) { pre->next = c; //pre為前一塊內存的地址 把后一塊的首地址賦給前一塊的尾 pre = c; //收尾連接后 pre指前一塊的功能就完成了 然后再指向現在的內存 為下一次拿內存、賦地址做准備 } initialize(c, num); //每取一塊地址就去輸入一次 ++num; }return h; } void traverse(struct person *head) { int index = 1; // 用於計數第幾個學生 while (head != NULL) { //同樣一直到后面沒有地址結束 printf("name is: %s\t ID is:%d\t chinese is:%d\t englishi is:%d\t math is:%d\n", head->name, head->ID, head->chinese, head->english, head->math); head = head->next; //前一個輸完后就要指向下一塊地址 ++index; } } int getlength(struct person *head) { int num = 0; while (head != NULL) { //當head指向后面沒有了 它就是NULL 結束 ++num; head = head->next; //如果head 不是NULL ++num后要把head指針指向最后 }return num; } //增加學生信息 void append_node(struct person *h) { struct person *t = h, *p; while (t->next != NULL) { t = t->next; }p = (struct person *)malloc(sizeof(struct person)); initialize(p, 0); p->next = NULL; t->next = p; traverse(h); } //刪除 struct person * delete_ID(struct person *head, int ID, int len) { struct person *t = head; struct person *temp; for (int i = 0; i < (len - 1); ++i) { if (i == 0) { if (head->ID == ID) { head = head->next; free(t); traverse(head); return head; } if ((t->next)->ID == ID) { temp = t->next; t->next = (t->next)->next; free(temp); traverse(head); return head; } } if (i != 0) { if ((t->next)->ID == ID) { temp = t->next; t->next = (t->next)->next; free(temp); traverse(head); return head; }t = t->next; } }return head; } //學號查詢 void search_ID(struct person *head, int ID) { while (head != NULL) { if (head->ID == ID) { printf("name is: %s\t ID is:%d\t chinese is:%d\t englishi is:%d math is:%d\n", head->name, head->ID, head->chinese, head->english, head->math); }head = head->next; } } //姓名查詢 void search_name(struct person *head, char name[20]) { while (head != NULL) { if ((strcmp(head->name, name)) == 0) { printf("name is: %s\t ID is:%d\t chinese is:%d\t englishi is:%d math is:%d\n", head->name, head->ID, head->chinese, head->english, head->math); } head = head->next; } } //指定學生修改 void change(struct person *head, char name[20]) { while (head != NULL) { if (strcmp(head->name, name) == 0) { printf(" name is:"); scanf_s("%s", &head->name, sizeof(head->name)); getchar(); printf("ID:"); scanf_s("%d", &head->ID); getchar(); printf("chinese:"); scanf_s("%d", &head->chinese); getchar(); printf("english:"); scanf_s("%d", &head->english); getchar(); printf("math:"); scanf_s("%d", &head->math); getchar(); } head = head->next; } traverse(head); } //數學分數平均數 int average_math(struct person *head, int len) { int i = 0, sum = 0, average; struct person *t = head; while (t != NULL) { sum += t->math; t = t->next; } average = (sum / len); return average; } //英語分數平均數 int average_english(struct person *head, int len) { int i = 0, sum = 0, average; struct person *t = head; while (t != NULL) { sum += t->english; t = t->next; } average = (sum / len); return average; } //語文分數平均數 int average_chinese(struct person *head, int len) { int sum = 0, average; struct person *t = head; while (t != NULL) { sum += t->chinese; t = t->next; } average = (sum / len); return average; } //成績區間統計 int statistics_math(struct person*head, int min, int max) { int conter = 0; while (head!= NULL) { if (head->math >= min&&head->math <= max) { ++conter; printf("name:%s math score:%d\n", head->name, head->math); }head = head->next; }return conter; } int statistics_chinese(struct person*head, int min, int max) { int conter = 0; while (head != NULL) { if (head->chinese >= min&&head->chinese <= max) { ++conter; printf("name:%s chinese score:%d\n", head->name, head->chinese); }head = head->next; }return conter; } int statistics_english(struct person*head, int min, int max) { int conter = 0; while (head != NULL) { if (head->english >= min&&head->english <= max) { ++conter; printf("name:%s english score:%d\n", head->name, head->english); }head = head->next; }return conter; } //某名學生的平均成績 int average_name(struct person*head, char name[20]) { int av = 0; while (head != NULL) { if (strcmp(head->name, name) == 0) { av += head->math; av += head->chinese; av += head->english; } head = head->next; } av = av / 3; return av; } //排序數學 void rank_math(struct person *h, int len) { struct person *t = h, *pre = h; int i, math, chinese, english,ID; char name[20]; t = t->next; for (i = 0; i < (len - 1); ++i) { while (t != NULL) { if ((t->math) >(pre->math)) { ID = t->ID; t->ID = pre->ID; pre->ID = ID; math = t->math; t->math = pre->math; pre->math = math; strcpy_s(name, t->name); strcpy_s(t->name, pre->name); strcpy_s(pre->name, name); chinese = t->chinese; t->chinese = pre->chinese; pre->chinese = chinese; english = t->english; t->english = pre->english; pre->english = english; } t = t->next; }pre = pre->next; t = pre->next; } traverse(h); } //排序語文 void rank_chinese(struct person *h, int len) { struct person *t = h, *pre = h; int i, math, chinese, english,ID; char name[20]; t = t->next; for (i = 0; i < (len - 1); ++i) { while (t != NULL) { if ((t->chinese) >(pre->chinese)) { ID = t->ID; t->ID = pre->ID; pre->ID = ID; math = t->math; t->math = pre->math; pre->math = math; strcpy_s(name, t->name); strcpy_s(t->name, pre->name); strcpy_s(pre->name, name); chinese = t->chinese; t->chinese = pre->chinese; pre->chinese = chinese; english = t->english; t->english = pre->english; pre->english = english; } t = t->next; }pre = pre->next; t = pre->next; } traverse(h); } //排序英語 void rank_english(struct person *h, int len) { struct person *t = h, *pre = h; int i, math, chinese, english,ID; char name[20]; t = t->next; for (i = 0; i < (len - 1); ++i) { while (t != NULL) { if ((t->english) >(pre->english)) { ID = t->ID; t->ID = pre->ID; pre->ID = ID; math = t->math; t->math = pre->math; pre->math = math; strcpy_s(name, t->name); strcpy_s(t->name, pre->name); strcpy_s(pre->name, name); chinese = t->chinese; t->chinese = pre->chinese; pre->chinese = chinese; english = t->english; t->english = pre->english; pre->english = english; } t = t->next; }pre = pre->next; t = pre->next; } traverse(h); } void release(struct person *head) { struct person *n; //需要一個指針存着下一個地址 while (head != NULL) { n = head->next; //把n指向下一塊要釋放的地址 free(head); head = n; //然后再把head從前一個地址移到下一個地址 } } //取長度 int getlen(struct person *head) { int conter = 0; struct person*t = head; while (t != NULL) { ++conter; t = t->next; } return conter; } //存入文件 void openfile(struct person *head, int len) { FILE *fp; struct person*t = head; errno_t err; int temp; char str[100]; char s[10]; if ((err = fopen_s(&fp, "D:\\學生信息", "w")) != 0) { printf("文件打開錯誤\n"); } else { printf("文件打開成功\n"); } for (int i = 0; i < len; ++i) { strcpy_s(str, t->name); fputs("name:", fp); fputs(str, fp); fputs(": ", fp); fputs("ID:", fp); sprintf_s(s, "%d", t->ID); fputs(s, fp); fputs(" ", fp); sprintf_s(s, "%d", t->chinese); fputs("chinese:", fp); fputs(s, fp); fputs(" ", fp); sprintf_s(s, "%d", t->math); fputs("math:", fp); fputs(s, fp); fputs(" ", fp); sprintf_s(s, "%d", t->english); fputs("english:", fp); fputs(s, fp); fputs("\n", fp); t = t->next; } return; } void menu(struct person *head, int len) { int m = 0; int min, max; int ID = 0; int conter = 0; char name[20]; while (1) { printf(" 請選擇您需要的操作:\n"); printf(" 0. 遍歷學生信息\n"); printf(" 1. 增加學生信息\n"); printf(" 2. 刪除學生信息\n"); printf(" 3. 修改學生信息\n"); printf(" 4. 按姓名查詢\n"); printf(" 5. 按學號查詢\n"); printf(" 6. 語文成績在某個區間段的人數以及學生\n"); printf(" 7. 數學成績在某個區間段的人數以及學生\n"); printf(" 8. 英語成績在某個區間段的人數以及學生\n"); printf(" 9. 語文平均分\n"); printf(" 10. 數學平均分\n"); printf(" 11. 英語平均分\n"); printf(" 12. 某個學生的三科平均成績\n"); printf(" 13. 按語文成績從高到低排序\n"); printf(" 14. 按數學成績從高到低排序\n"); printf(" 15. 按英語成績從高到底排序\n"); printf(" 16. 結束功能並把信息寫入文件中\n"); scanf_s("%d", &m); switch (m) { case 0: traverse(head); break; case 1: append_node(head); break; case 2: {printf("要刪除學生信息的學號:"); scanf_s("%d", &ID); head=delete_ID(head, ID, getlen(head)); }break; case 3: {printf("需要修改學生信息的同學姓名:"); scanf_s("%s", &name, sizeof(name)); change(head, name); }break; case 4: {printf("search by name:"); scanf_s("%s", &name, sizeof(name)); search_name(head, name); }break; case 5: {printf("學號查詢:"); scanf_s("%d", &ID); search_ID(head, ID); }break; case 6: {printf("請輸入語文成績的區間:"); printf("min="); scanf_s("%d", &min); printf("max="); scanf_s("%d", &max); printf("語文成績在區間%d到%d之間的學生:%d人\n", min, max, statistics_chinese(head, min, max)); }break; case 7: {printf("請輸入數學成績的區間:"); printf("min="); scanf_s("%d", &min); printf("max="); scanf_s("%d", &max); printf("數學成績在區間%d到%d之間的學生:%d人\n", min, max, statistics_math(head, min, max)); }break; case 8: {printf("請輸入英語成績的區間:"); printf("min="); scanf_s("%d", &min); printf("max="); scanf_s("%d", &max); printf("英語成績在區間%d到%d之間的學生:共有%d人\n", min, max, statistics_english(head, min, max)); }break; case 9: { printf("average of chinese is%d", average_chinese(head, getlen(head))); }break; case 10: { printf("average of math is%d", average_math(head, getlen(head))); }break; case 11: { printf("average of english is%d", average_english(head, getlen(head))); }break; case 12: {printf("請輸入學生的姓名:"); scanf_s("%s", &name, sizeof(name)); printf("%s 的平均成績為:%d", name, average_name(head, name)); }break; case 13: {printf("按照語文成績從高到底排序:"); rank_chinese(head, getlen(head)); }break; case 14: {printf("按照數學成績從高到底排序:"); rank_math(head, getlen(head)); }break; case 15: {printf("按照英語成績從高到底排序:"); rank_english(head, getlen(head)); }break; case 16: openfile(head, getlen(head)); return; } } } int main() { struct person *head; int len; int min, max; int ID = 0; char name[20]; printf("請輸入學生信息"); printf("學生人數:"); scanf_s("%d", &len); //輸入要取的地址多少 head = create(len); // 創建地址 在create里面就有初始復制函數嵌套 traverse(head); //遍歷 menu(head, getlen(head)); release(head); //釋放內存 system("pause"); return 0; }