C语言——第五次笔记

学生管理系统

1.明确功能

2.数据存储

3.准备知识

  • 3.1 枚举

  • 3.2 链表 (单链表,循环链表,双向链表,双向循环链表)

4. 项目(待续)

1.明确功能

A. 学生:

  • 查询个人详细信息。
  • 查询某个课程成绩。
  • 选择课程。

B. 老师:

  • 查询个人详细信息。
  • 给某个学生的某个课程打分。
  • 申请课程。

C. 管理员:

  • 查询所有学生信息。
  • 查询所有老师信息。
  • 查询某一个用户的详细信息。
  • 添加一个老师信息。
  • 添加一个学生信息。
  • 添加一个管理员信息。

2.数据存储

1. 常规存储数据手段->数据库(没有学)->文件。

2. 保存哪些数据:

  • a.保存所有用户的基本信息,例如users.txt文件。
  • b.保存具体的一个用户的详细信息,例如用户名.txt文件。

3.准备知识

3.1 枚举

  • 3.1.1 定义枚举类型

1.枚举语法定义格式:

enum 枚举名 {
 枚举元素1,
 枚举元素2,
 .........,
 枚举元素n
};

2.枚举成员的值:

  • 第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 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,  //学生 
  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);

   /* 输出结果 */
   switch (favorite_color){
   case red:
       printf("你喜欢的颜色是红色");
       break;
   case green:
       printf("你喜欢的颜色是绿色");
       break;
   case blue:
       printf("你喜欢的颜色是蓝色");
       break;
   default:
       printf("你没有选择你喜欢的颜色");
   }

   return 0;
}

//运行
请输入你喜欢的颜色: (1. red, 2. green, 3. blue): 1
你喜欢的颜色是红色

3.2 链表(单链表,循环链表,双向链表,双向循环链表)

1.区别:


2.单链表的操作代码:

#include<stdio.h>
#include<malloc.h>
#include<assert.h>

//方便修改数据域里面的类型 
#define ElemType int

//定义结点
typedef struct ListNode
{
 ElemType data;
 struct ListNode *next;
}ListNode,*PNode;

//定义链表
typedef struct LinkList
{
 PNode first;
 PNode last;
 size_t size;
}LinkList;

//初始化函数
void InitList(LinkList *list);

//尾插函数
void push_back(LinkList *list,ElemType x);

//头插函数
void push_front(LinkList *list,ElemType x);

//尾删函数
void pop_back(LinkList *list);

//头删函数
void pop_front(LinkList *list);

//显示函数
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);

//主函数
int main()
{
 LinkList mylist;
 InitList(&mylist);


 ElemType Item;
 ListNode *P = NULL;//初始化find所找的结点
 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("请输入要插入的数据(-1结束):>");
         while (scanf("%d",&Item),Item != -1)
         {
             push_back(&mylist,Item);
         }
         break;
     case 2://头插
         printf("请输入要插入的数据(-1结束):>");
         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("请输入要插入的数据:>");
         scanf("%d",&Item);
         insert_val(&mylist,Item);
         printf("插入成功\n");
         break;
     case 7://查找
         printf("请输入要查找的数据:>");
         scanf("%d",&Item);
         P = find(&mylist,Item);
         break;
     case 8://链表长度
         printf("链表的长度为%d.\n",length(&mylist));
         break;
     case 9://按值删除
         printf("请输入要删除的数据:>");
         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://结束
         break;
     default:
         printf("输入的数据不合法,请重新输入");
         break;
     }
 }

 return 0;
}


//初始化函数
void InitList(LinkList *list)
{
 //开辟first和last的空间,初始状态指向同一个结点
 list->first = list->last = (ListNode*)malloc(sizeof(ListNode));
 assert(list->first != NULL);
 //初始化first和last
 list->first->next = NULL;
 //初始化链表的长度为0
 list->size = 0;
}

//尾插函数
void push_back(LinkList *list,ElemType x)
{
 //创造一个结点
 ListNode *s = (ListNode *)malloc(sizeof(ListNode));
 assert(s != NULL);
 //结点赋值
 s->data = x;
 s->next = NULL;
 //调整指向关系(包含了空链表的情况)
 list->last->next = s;
 list->last = s;
 //更改链表长度
 list->size++;
}

//头插函数
void push_front(LinkList *list,ElemType x)
{
 //创建一个结点
 ListNode *s = (ListNode *)malloc(sizeof(ListNode));
 assert(s != NULL);
 //结点赋值与指向关系
 s->data = x;
 s->next = list->first->next;
 list->first->next = s;
 //空链表的情况
 if (list->size == 0)
 {
     list->last = s;
 }
 //更改链表的长度
 list->size++;
}

//尾删函数
void pop_back(LinkList *list)
{
 //空链表的情况下,直接返回
 if (list->size == 0)
 {
     return;
 }
 //非空链表下
 //创建一个结点,循环找到尾结点之前的结点
 ListNode *p = list->first;
 while (p->next != list->last)
 {
     p = p->next;
 }
 //当一个节点的下一个结点=尾结点时,结束循环
 //释放尾结点
 free(list->last);
 //调整指向关系
 list->last = p;
 list->last->next = NULL;
 //更改链表长度
 list->size--;
}

//头删函数
void pop_front(LinkList *list)
{
 //空链表的情况下,直接返回
 if(list->size == 0)
 {
     return;
 }
 //非空链表情况
 //调整指向关系
 ListNode *p = list->first->next;
 list->first->next = p->next;
 //释放
 free(p);
 //链表长度为1时,调整尾结点指向关系
 if(list->size == 1)
 {
     list->last = list->first;
 }
 //更改链表长度
 list->size--;
}

//显示函数
void show_list(LinkList *list)
{
 //创建结点用首元结点初始化
 ListNode *p = list->first->next;
 //循环取值
 while (p != NULL)
 {
     printf("%d-->",p->data);
     p = p->next;
 }
 //当结点指针域所指向的结点为NULL时结束循环
 printf("NULL.\n");
}

//按值插入
void insert_val(LinkList *list,ElemType x)
{
 //创建一个结点
 ListNode *s = (ListNode*)malloc(sizeof(ListNode));
 assert(s != NULL);
 //结点赋值
 s->data = x;
 s->next = NULL;
 //循环找位置
 ListNode *p = list->first;
 while (p->next != NULL && p->next->data < x)
 {
     p = p->next;
 }
 //某个结点指针域所指向的下一个结点为NULL或者其数据域的值>=x结束循环
 if (p->next == NULL)
 {
     //没有找到所给结点,直接尾插
     list->last = s;
 }
 //调整指向关系
 s->next = p->next;
 p->next = s;
 //更改链表长度
 list->size++;

}

//查找
ListNode* find(LinkList *list,ElemType x)
{
 //循环找出
 ListNode *p = list->first->next;
 while (p != NULL && p->data != x)
 {
     p = p->next;
 }
 //结点为空或者其数据=x结束循环
 if (p ==  NULL)
 {
     //链表中没有该数据的情况下
     printf("链表中没有这个数据\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函数找到位置
 ListNode *p = find(list,x);
 //链表中没有该数据
 if (p == NULL)
 {
     printf("要删除的数据不存在.\n");
     return;
 }
 //删除的是链表中最后一个数字
 if (p == list->last)
 {
     pop_back(list);
 }
 else
 {
     //创建结点用要被删除的结点下一个结点初始化
     ListNode *q = p->next;
     //令要被删除的节点的数据等于下一个结点的数据
     p->data = q->data;
     //调整指向关系
     p->next = q->next;
     //删除要被删除的结点下一个结点
     free(q);
     //更改链表长度
     list->size--;
 }
 printf("删除成功.\n");
}

//顺序
void sort(LinkList *list)
{
 //链表为空或者长度为1
 if (list->size == 0 || list->size == 1)
 {
     return;
 }
 //链表不为空或者长度不为1
 //创建结点
 ListNode *s = list->first->next;
 ListNode *q = s->next;
 //拆分链表
 list->last = s;
 list->last->next = NULL;
 while (q != NULL)
 {
     s = q;
     q = q->next;
     //循环找位置
     ListNode *p = list->first;
     while (p->next != NULL && p->next->data < s->data)
     {
         p = p->next;
     }
     //某个结点指针域所指向的下一个结点为NULL或者其数据域的值>=x结束循环
     if(p->next == NULL)
     {
         //没有找到结点,直接尾插
         list->last = s;
     }
     //调整指向关系
     s->next = p->next;
     p->next = s;
 }

}

//逆值
void resver(LinkList *list)
{
 //链表为空或者长度为1
 if (list->size == 0 || list->size == 1)
 {
     return;
 }
 //链表不为空或者长度不为1
 //创建结点
 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; 
 //循环删除结点,先依次删除first->next后面的结点,最后删除first->next结点
 while (p != NULL)
 {
     list->first ->next = p->next;
     free(p);
     p = list->first->next;
 }
 //当p为空时,结束循环
 list->last = list->first;
 //更改链表长度
 list->size = 0;      
}

//销毁
void destroy(LinkList *list)
{
 clear(list);
 free(list->first);
 list->first = list->last = NULL;
}

3.单链表的操作结果:

4. 项目

东哥讲完后,会继续补充

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容