學(xué)生管理系統(tǒng)
1.明確功能
2.數(shù)據(jù)存儲
3.準(zhǔn)備知識
3.1 枚舉
3.2 鏈表
(單鏈表,循環(huán)鏈表,雙向鏈表,雙向循環(huán)鏈表)
4. 項(xiàng)目(待續(xù))
1.明確功能
A. 學(xué)生:
- 查詢個人詳細(xì)信息。
- 查詢某個課程成績。
- 選擇課程。
B. 老師:
- 查詢個人詳細(xì)信息。
- 給某個學(xué)生的某個課程打分。
- 申請課程。
C. 管理員:
- 查詢所有學(xué)生信息。
- 查詢所有老師信息。
- 查詢某一個用戶的詳細(xì)信息。
- 添加一個老師信息。
- 添加一個學(xué)生信息。
- 添加一個管理員信息。
2.數(shù)據(jù)存儲
1. 常規(guī)存儲數(shù)據(jù)手段->數(shù)據(jù)庫(沒有學(xué))->文件。
2. 保存哪些數(shù)據(jù):
- a.保存所有用戶的基本信息,例如users.txt文件。
- b.保存具體的一個用戶的詳細(xì)信息,例如用戶名.txt文件。
3.準(zhǔn)備知識
3.1 枚舉
3.1.1 定義枚舉類型
1.枚舉語法定義格式:
enum 枚舉名 { 枚舉元素1, 枚舉元素2, ........., 枚舉元素n };
2.枚舉成員的值:
第一個枚舉成員的默認(rèn)值為整型的 0,后續(xù)枚舉成員的值在前一個成員上加 1。
沒有指定值的枚舉元素,其值為前一元素加 1
3.定義枚舉類型例子
//第一個枚舉成員的值定義為 1,第二個就為 2,以此類推。 enum DAY{ MON = 1, TUE, WED, THU, FRI, SAT, SUN };
enum season { spring, //0 summer = 3, //3 autumn, //4 winter //5 };
3.1.2 定義枚舉變量
1.先定義枚舉類型,再定義枚舉變量
enum DAY{ MON=1, TUE, WED, THU, FRI, SAT, SUN }; enum DAY day;
2.定義枚舉類型的同時定義枚舉類型
enum DAY{ MON=1, TUE, WED, THU, FRI, SAT, SUN } day;
3.省略枚舉名稱,直接定義枚舉
enum{ MON=1, TUE, WED, THU, FRI, SAT, SUN } day;
4.使用
typedef
為變量重定義一個名字。//用戶類型 typedef enum { UserTypeNone, //沒有身份 UserTypeStudent, //學(xué)生 UserTypeTeacher, //老師 UserTypeAdmin //管理員 }UserType; UserType type;
3.1.3 枚舉在switch中的使用
#include <stdio.h> #include <stdlib.h> int main(){ enum color { red=1, green, blue }; enum color favorite_color; /* ask user to choose color */ printf("請輸入你喜歡的顏色: (1. red, 2. green, 3. blue): "); scanf("%d", &favorite_color); /* 輸出結(jié)果 */ switch (favorite_color){ case red: printf("你喜歡的顏色是紅色"); break; case green: printf("你喜歡的顏色是綠色"); break; case blue: printf("你喜歡的顏色是藍(lán)色"); break; default: printf("你沒有選擇你喜歡的顏色"); } return 0; } //運(yùn)行 請輸入你喜歡的顏色: (1. red, 2. green, 3. blue): 1 你喜歡的顏色是紅色
3.2 鏈表(單鏈表,循環(huán)鏈表,雙向鏈表,雙向循環(huán)鏈表)
1.區(qū)別:
2.單鏈表的操作代碼:
#include<stdio.h> #include<malloc.h> #include<assert.h> //方便修改數(shù)據(jù)域里面的類型 #define ElemType int //定義結(jié)點(diǎn) typedef struct ListNode { ElemType data; struct ListNode *next; }ListNode,*PNode; //定義鏈表 typedef struct LinkList { PNode first; PNode last; size_t size; }LinkList; //初始化函數(shù) void InitList(LinkList *list); //尾插函數(shù) void push_back(LinkList *list,ElemType x); //頭插函數(shù) void push_front(LinkList *list,ElemType x); //尾刪函數(shù) void pop_back(LinkList *list); //頭刪函數(shù) void pop_front(LinkList *list); //顯示函數(shù) void show_list(LinkList *list); //按值插入 void insert_val(LinkList *list,ElemType x); //查找 ListNode* find(LinkList *list,ElemType x); //鏈表長度 int length(LinkList *list); //按值刪除 void delete_val(LinkList *list,ElemType x); //順序 void sort(LinkList *list); //逆值 void resver(LinkList *list); //清空 void clear(LinkList *list); //銷毀 void destroy(LinkList *list); //主函數(shù) int main() { LinkList mylist; InitList(&mylist); ElemType Item; ListNode *P = NULL;//初始化find所找的結(jié)點(diǎn) int select; while (1) { printf("*************************************\n"); printf("*[1].push_back [2].push_front *\n"); printf("*[3].pop_back [4].pop_front *\n"); printf("*[5].show_list [6].insert_val *\n"); printf("*[7].find [8].length *\n"); printf("*[9].delete_val [10].sort *\n"); printf("*[11].resver [12].clear *\n"); printf("*[13].quit_system [*]destroy *\n"); printf("*************************************\n"); printf("請選擇:>"); scanf("%d",&select); switch (select) { case 1://尾插 printf("請輸入要插入的數(shù)據(jù)(-1結(jié)束):>"); while (scanf("%d",&Item),Item != -1) { push_back(&mylist,Item); } break; case 2://頭插 printf("請輸入要插入的數(shù)據(jù)(-1結(jié)束):>"); while (scanf("%d",&Item),Item != -1) { push_front(&mylist,Item); } break; case 3://尾刪 pop_back(&mylist); printf("成功尾刪\n"); break; case 4://頭刪 pop_front(&mylist); printf("成功頭刪\n"); break; case 5://顯示 show_list(&mylist); break; case 6://按值插入 //插在所給值前面的位置 printf("請輸入要插入的數(shù)據(jù):>"); scanf("%d",&Item); insert_val(&mylist,Item); printf("插入成功\n"); break; case 7://查找 printf("請輸入要查找的數(shù)據(jù):>"); scanf("%d",&Item); P = find(&mylist,Item); break; case 8://鏈表長度 printf("鏈表的長度為%d.\n",length(&mylist)); break; case 9://按值刪除 printf("請輸入要刪除的數(shù)據(jù):>"); scanf("%d",&Item); delete_val(&mylist,Item); break; case 10://順序 sort(&mylist); printf("排序完成.\n"); break; case 11://逆值 resver(&mylist); printf("逆值完成.\n"); break; case 12://清空 clear(&mylist); printf("清空完成.\n"); break; case 13://結(jié)束 break; default: printf("輸入的數(shù)據(jù)不合法,請重新輸入"); break; } } return 0; } //初始化函數(shù) void InitList(LinkList *list) { //開辟first和last的空間,初始狀態(tài)指向同一個結(jié)點(diǎn) list->first = list->last = (ListNode*)malloc(sizeof(ListNode)); assert(list->first != NULL); //初始化first和last list->first->next = NULL; //初始化鏈表的長度為0 list->size = 0; } //尾插函數(shù) void push_back(LinkList *list,ElemType x) { //創(chuàng)造一個結(jié)點(diǎn) ListNode *s = (ListNode *)malloc(sizeof(ListNode)); assert(s != NULL); //結(jié)點(diǎn)賦值 s->data = x; s->next = NULL; //調(diào)整指向關(guān)系(包含了空鏈表的情況) list->last->next = s; list->last = s; //更改鏈表長度 list->size++; } //頭插函數(shù) void push_front(LinkList *list,ElemType x) { //創(chuàng)建一個結(jié)點(diǎn) ListNode *s = (ListNode *)malloc(sizeof(ListNode)); assert(s != NULL); //結(jié)點(diǎn)賦值與指向關(guān)系 s->data = x; s->next = list->first->next; list->first->next = s; //空鏈表的情況 if (list->size == 0) { list->last = s; } //更改鏈表的長度 list->size++; } //尾刪函數(shù) void pop_back(LinkList *list) { //空鏈表的情況下,直接返回 if (list->size == 0) { return; } //非空鏈表下 //創(chuàng)建一個結(jié)點(diǎn),循環(huán)找到尾結(jié)點(diǎn)之前的結(jié)點(diǎn) ListNode *p = list->first; while (p->next != list->last) { p = p->next; } //當(dāng)一個節(jié)點(diǎn)的下一個結(jié)點(diǎn)=尾結(jié)點(diǎn)時,結(jié)束循環(huán) //釋放尾結(jié)點(diǎn) free(list->last); //調(diào)整指向關(guān)系 list->last = p; list->last->next = NULL; //更改鏈表長度 list->size--; } //頭刪函數(shù) void pop_front(LinkList *list) { //空鏈表的情況下,直接返回 if(list->size == 0) { return; } //非空鏈表情況 //調(diào)整指向關(guān)系 ListNode *p = list->first->next; list->first->next = p->next; //釋放 free(p); //鏈表長度為1時,調(diào)整尾結(jié)點(diǎn)指向關(guān)系 if(list->size == 1) { list->last = list->first; } //更改鏈表長度 list->size--; } //顯示函數(shù) void show_list(LinkList *list) { //創(chuàng)建結(jié)點(diǎn)用首元結(jié)點(diǎn)初始化 ListNode *p = list->first->next; //循環(huán)取值 while (p != NULL) { printf("%d-->",p->data); p = p->next; } //當(dāng)結(jié)點(diǎn)指針域所指向的結(jié)點(diǎn)為NULL時結(jié)束循環(huán) printf("NULL.\n"); } //按值插入 void insert_val(LinkList *list,ElemType x) { //創(chuàng)建一個結(jié)點(diǎn) ListNode *s = (ListNode*)malloc(sizeof(ListNode)); assert(s != NULL); //結(jié)點(diǎn)賦值 s->data = x; s->next = NULL; //循環(huán)找位置 ListNode *p = list->first; while (p->next != NULL && p->next->data < x) { p = p->next; } //某個結(jié)點(diǎn)指針域所指向的下一個結(jié)點(diǎn)為NULL或者其數(shù)據(jù)域的值>=x結(jié)束循環(huán) if (p->next == NULL) { //沒有找到所給結(jié)點(diǎn),直接尾插 list->last = s; } //調(diào)整指向關(guān)系 s->next = p->next; p->next = s; //更改鏈表長度 list->size++; } //查找 ListNode* find(LinkList *list,ElemType x) { //循環(huán)找出 ListNode *p = list->first->next; while (p != NULL && p->data != x) { p = p->next; } //結(jié)點(diǎn)為空或者其數(shù)據(jù)=x結(jié)束循環(huán) if (p == NULL) { //鏈表中沒有該數(shù)據(jù)的情況下 printf("鏈表中沒有這個數(shù)據(jù)\n"); } return p; } //鏈表長度 int length(LinkList *list) { return list->size; } //按值刪除 void delete_val(LinkList *list,ElemType x) { //鏈表為空的情況下 if (list->size == 0) { printf("鏈表為空.\n"); return; } //find函數(shù)找到位置 ListNode *p = find(list,x); //鏈表中沒有該數(shù)據(jù) if (p == NULL) { printf("要刪除的數(shù)據(jù)不存在.\n"); return; } //刪除的是鏈表中最后一個數(shù)字 if (p == list->last) { pop_back(list); } else { //創(chuàng)建結(jié)點(diǎn)用要被刪除的結(jié)點(diǎn)下一個結(jié)點(diǎn)初始化 ListNode *q = p->next; //令要被刪除的節(jié)點(diǎn)的數(shù)據(jù)等于下一個結(jié)點(diǎn)的數(shù)據(jù) p->data = q->data; //調(diào)整指向關(guān)系 p->next = q->next; //刪除要被刪除的結(jié)點(diǎn)下一個結(jié)點(diǎn) free(q); //更改鏈表長度 list->size--; } printf("刪除成功.\n"); } //順序 void sort(LinkList *list) { //鏈表為空或者長度為1 if (list->size == 0 || list->size == 1) { return; } //鏈表不為空或者長度不為1 //創(chuàng)建結(jié)點(diǎn) ListNode *s = list->first->next; ListNode *q = s->next; //拆分鏈表 list->last = s; list->last->next = NULL; while (q != NULL) { s = q; q = q->next; //循環(huán)找位置 ListNode *p = list->first; while (p->next != NULL && p->next->data < s->data) { p = p->next; } //某個結(jié)點(diǎn)指針域所指向的下一個結(jié)點(diǎn)為NULL或者其數(shù)據(jù)域的值>=x結(jié)束循環(huán) if(p->next == NULL) { //沒有找到結(jié)點(diǎn),直接尾插 list->last = s; } //調(diào)整指向關(guān)系 s->next = p->next; p->next = s; } } //逆值 void resver(LinkList *list) { //鏈表為空或者長度為1 if (list->size == 0 || list->size == 1) { return; } //鏈表不為空或者長度不為1 //創(chuàng)建結(jié)點(diǎn) ListNode *p = list->first->next; ListNode *q = p->next; //拆分鏈表 list->last = p; list->last->next = NULL; while (q != NULL) { //取值頭插 p = q; q = p->next; p->next = list->first->next; list->first->next = p; } } //清空 void clear(LinkList *list) { //鏈表為空 if (list->size == 0) { return; } //鏈表不為空 ListNode *p = list->first->next; //循環(huán)刪除結(jié)點(diǎn),先依次刪除first->next后面的結(jié)點(diǎn),最后刪除first->next結(jié)點(diǎn) while (p != NULL) { list->first ->next = p->next; free(p); p = list->first->next; } //當(dāng)p為空時,結(jié)束循環(huán) list->last = list->first; //更改鏈表長度 list->size = 0; } //銷毀 void destroy(LinkList *list) { clear(list); free(list->first); list->first = list->last = NULL; }
3.單鏈表的操作結(jié)果:
4. 項(xiàng)目
東哥講完后,會繼續(xù)補(bǔ)充