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 
#include 
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.区别:

C语言——第五次笔记_第1张图片

C语言——第五次笔记_第2张图片

2.单链表的操作代码:

#include
#include
#include

//方便修改数据域里面的类型 
#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. 项目

东哥讲完后,会继续补充

你可能感兴趣的:(C语言——第五次笔记)