美文网首页
C语言——第五次笔记

C语言——第五次笔记

作者: 小石头呢 | 来源:发表于2019-12-23 20:14 被阅读0次

    学生管理系统

    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. 项目

    东哥讲完后,会继续补充

    相关文章

      网友评论

          本文标题:C语言——第五次笔记

          本文链接:https://www.haomeiwen.com/subject/uptonctx.html