Sirenarya 发表于 2023-6-6 20:06:56

新手,想知道这个代码怎么分析

    新手,想分析这个代码的整个框架但是不太会,做的是一个窗口排队管理系统

#include <stdio.h>
#include "util.h"


typedef enum
{
    TYPE_A,// 业务类型A
    TYPE_B,// 业务类型B
    TYPE_C,// 业务类型C
    TYPE_D   // 业务类型D
} WindowType;

typedef enum
{
    STATUS_NORMAR,   //正常0
    STATUS_PAUSED      //暂停1
} WindowStatus;

typedef struct
{
   int windowId;
   WindowType type;
   WindowStatus zhuangtai;
   int people;
   int totalrating;
   int totalCustomers;
}Window;

typedef struct WNode
{
    Window data;//窗口数据
    struct WNode *next;
}*WinList;

WinList WL;

void CreateWin()
{
    WL=NULL;
}

//获取窗口链表最后一个窗口
WinList GetTail ( )
{
    if ( WL == NULL ) { //链表为空
      return NULL;
    } else {
      WinList node = WL;
      while (node->next != NULL) {
            node = node->next; //遍历链表
      }
      return node; //返回链表的尾节点
    }
}




WinList GetTail ( );
void OnWinShow(void *para);
void OnWinNew(void *para);
void OnWinDel(void *para);
void OnWinPause(void *para);
void OnWinResume(void *para);
void OnCustomerArrive(void *para);
void OnCustomerLeave(void *para);

void OnWinManage(void *para)
{
        SCmd acmd[] = {{"WinShow",   "窗口状态",         OnWinShow},
                   {"WinNew",    "窗口新增",         OnWinNew},
                   {"WinDel",    "窗口删除",         OnWinDel},
                   {"WinPause","窗口业务暂停",   OnWinPause},
                   {"WinResume", "窗口业务恢复",   OnWinResume},
                   {"CustomerArrive","取号排队",   OnCustomerArrive},
                   {"CustomerLeave",   "办结离队",   OnCustomerLeave}
        };

        CmdLoop(acmd, numof(acmd), NULL);
}

void OnWinShow(void *para)
{
    if(WL==NULL){
      printf("没有文件\n\n");
    }
    printf ( "窗口编号\t业务类型\t排队人数\t窗口状态\t窗口评分\t总接待人数\n" );
    WinList P = WL;
    while(P!=NULL){
      Window win = P->data;
      printf ("%4d\t   ", win.windowId);
      switch ( win.type ) {// 根据窗口所属业务类型输出对应的字母
                     case TYPE_A:
                            printf ( "A-个人现金业务\t" );
                            break;
                     case TYPE_B:
                            printf ( "B-个人其他业务\t" );
                            break;
                     case TYPE_C:
                            printf ( "C-对公现金业务\t" );
                            break;
                     case TYPE_D:
                            printf ( "D-对公其他业务\t" );
                            break;
      }
      int length = win.people;
      printf ( "%4d\t\t", length );
      switch ( win.zhuangtai ) {   // 根据窗口状态输出对应的文字
                     case STATUS_NORMAR:
                            printf ( "正常\t\t" );
                            break;
                     case STATUS_PAUSED:
                            printf ( "暂停\t\t" );
                            break;
      }
      int averageRating = 0;
      if (win.totalCustomers > 0) {
            averageRating = win.totalrating / win.totalCustomers;
      }
      printf ( "%4d\t\t", averageRating );
      printf ( "%4d\t\t\n", win.people );
      P=P->next;
    }
    printf("\n");
}
//窗口新增
void OnWinNew(void *para)
{
    WinList winTail = GetTail ( );
    printf("请输入窗口类型(A-个人现金业务,B-个人其他业务,C-对公现金业务,D-对公其他业务)\n");
    char ch;
    scanf(" %c", &ch);
    getchar();// 清除换行符
    if( ch>'D' || ch<'A'){
      printf ( "操作失误\n\n" );
      return;
    }
    WinList newList = ( WinList ) malloc ( sizeof ( struct WNode ));
    newList->data.type= (WindowType)(ch - 'A') ;
    newList->data.zhuangtai=STATUS_NORMAR;
    newList->data.people = 0; // 初始化排队人数为 0
    newList->data.totalCustomers=0;
    newList->data.totalrating=0;
    newList->next = NULL;
    if(winTail==NULL){
      newList->data.windowId=1;
      WL=newList;
    }else{
      newList->data.windowId=winTail->data.windowId+1;
      winTail->next = newList;
    }
    printf("窗口编号 %d 创建成功\n", newList->data.windowId);
}

void OnWinDel(void *para)
{
   // 读取窗口编号
    printf("请输入要删除的窗口编号:\n");
    int windowId;
    scanf("%d", &windowId);
    getchar();// 清除换行符

    // 遍历窗口链表,找到要删除的窗口
    WinList prev = NULL;
    WinList curr = WL;
    while (curr != NULL) {
      if (curr->data.windowId == windowId) {
            // 找到窗口,删除窗口节点
            if (prev == NULL) {
                // 要删除的是头节点
                WL = curr->next;
            } else {
                prev->next = curr->next;
            }
            free(curr);
            printf("窗口 %d 已删除\n", windowId);
            return;
      }
      prev = curr;
      curr = curr->next;
    }

    // 若未找到要删除的窗口
    printf("未找到窗口编号为 %d 的窗口\n", windowId);
}

//窗口业务暂停
void OnWinPause(void *para)
{
    // 读取窗口编号
    printf("请输入窗口编号:\n");
    int windowId;
    scanf("%d", &windowId);
    getchar();// 清除换行符

    // 遍历窗口链表,找到对应窗口
    WinList P = WL;
    while (P != NULL) {
      if (P->data.windowId == windowId) {
            // 找到窗口,将窗口状态设置为暂停
            P->data.zhuangtai = STATUS_PAUSED;
            printf("窗口 %d 业务已暂停\n", windowId);
            break;
      }
      P = P->next;
    }
}

//窗口业务恢复
void OnWinResume(void *para)
{
    // 读取窗口编号
    printf("请输入窗口编号:\n");
    int windowId;
    scanf("%d", &windowId);
    getchar();// 清除换行符

    // 遍历窗口链表,找到对应窗口
    WinList P = WL;
    while (P != NULL) {
      if (P->data.windowId == windowId) {
            P->data.zhuangtai = STATUS_NORMAR;
            printf("窗口 %d 业务已恢复\n", windowId);
            break;
      }
      P = P->next;
    }
}

void OnCustomerArrive(void *para)
{
    int windowId;
    printf("请输入窗口编号:");
    scanf("%d", &windowId);
    getchar(); // 清除换行符

    WinList P = WL;
    while (P != NULL) {
      if (P->data.windowId == windowId) {
            if (P->data.zhuangtai == STATUS_PAUSED) {
                printf("窗口暂停服务,无法取号排队\n");
                return;
            }
            P->data.people++; // 排队人数增加
            printf("窗口编号 %d 的排队人数增加为 %d\n", windowId, P->data.people);
            return;
      }
      P = P->next;
    }

    printf("窗口编号 %d 不存在\n", windowId);
}

void OnCustomerLeave(void *para)
{
    // 读取窗口编号
    printf("请输入窗口编号:\n");
    int windowId;
    scanf("%d", &windowId);
    getchar();// 清除换行符

    // 遍历窗口链表,找到对应窗口
    WinList P = WL;
    while (P != NULL) {
      if (P->data.windowId == windowId) {
                if (P->data.zhuangtai == STATUS_PAUSED) {
                printf("窗口暂停服务,无法办理离队\n");
                return;
            }
            // 找到窗口,将排队人数减一
            if (P->data.people > 0) {
                P->data.people--;
                P->data.totalCustomers++;
                // 读取顾客评分
                printf("请输入顾客评分(1-10):\n");
                int rating;
                scanf("%d", &rating);
                getchar();// 清除换行符

                // 更新窗口评分总和
                P->data.totalrating += rating;
                printf("客户办理离队成功,当前排队人数:%d\n", P->data.people);
            } else {
                printf("窗口 %d 没有待办客户\n", windowId);
            }
            break;
      }
      P = P->next;
    }

    // 若未找到对应窗口
    if (P == NULL) {
      printf("未找到窗口编号为 %d 的窗口\n", windowId);
    }
}

isdkz 发表于 2023-6-6 20:18:10

这个程序是一个窗口排队管理系统,主要使用了链表数据结构来存储和操作每个窗口的信息。下面是一些代码中主要部分的解释:

1. 类型定义(typedef):
    ·WindowType是一个枚举类型,用于表示窗口所属的业务类型,包含四种类型。
    ·WindowStatus是一个枚举类型,用于表示窗口的状态,正常或暂停。
    ·Window是一个结构体类型,表示一个窗口,包含窗口ID、业务类型、窗口状态、当前排队人数、总评分和总接待人数等字段。
    ·WinList是一个链表结构体类型,用于表示窗口链表。每个链表节点包含一个 Window 数据和一个指向下一个节点的指针。

2. 函数功能解析:
    ·CreateWin函数用于创建一个新的窗口链表。
    ·GetTail函数用于获取窗口链表的尾部节点。
    ·OnWinShow函数用于显示窗口链表中所有窗口的状态。
    ·OnWinNew函数用于新增一个窗口节点到窗口链表。
    ·OnWinDel函数用于从窗口链表中删除一个窗口节点。
    ·OnWinPause函数用于暂停窗口的业务。
    ·OnWinResume函数用于恢复窗口的业务。
    ·OnCustomerArrive函数用于处理客户到达窗口排队的事件,如果窗口业务未暂停,则增加排队人数。
    ·OnCustomerLeave函数用于处理客户离开窗口的事件,如果窗口有待办客户且业务未暂停,则减少排队人数,增加总接待人数,并记录顾客的评分。

3. 链表的使用:
   链表是一种常见的数据结构,它可以用于存储多个相同类型的数据。每个链表节点包含数据部分和指向下一个节点的指针。这个程序中的窗口链表就是一个单链表,通过 WinList 类型定义。链表操作主要通过遍历链表实现。

总的来说,这个窗口排队管理系统使用链表数据结构来存储和操作每个窗口的信息,可以进行新增窗口、删除窗口、暂停和恢复窗口业务、客户排队和离队等操作,可以根据具体的业务需求进行修改和扩展。

sfqxx 发表于 2023-6-6 20:27:35

这是一段实现窗口队列管理系统的代码,使用C语言编写,并包含多个用于管理窗口和顾客的函数。

首先,该代码定义了多个数据结构,包括四种不同窗口类型的枚举、另一个用于窗口状态的枚举,以及两个结构体,一个用于存储关于窗口的信息,另一个用于创建窗口链表。

该代码中的主函数定义了多个回调函数来处理用户输入的命令。这些命令包括显示当前窗口状态、添加新的窗口、删除现有窗口、暂停某个窗口业务操作、恢复某个窗口业务操作、添加顾客到队列以及从队列中移除顾客。

OnWinManage 函数启动命令循环并根据用户输入执行相应的回调函数。例如,如果用户输入“WinShow”,程序调用 OnWinShow 函数,该函数打印链接列表中每个窗口的当前状态。

OnWinNew 函数创建具有唯一ID、指定窗口类型的新窗口,并初始化表示窗口状态、排队人数等其他字段。

OnWinDel 函数删除与提供的窗口ID相匹配的窗口。

OnWinPause 使用 STATUS_PAUSED 枚举设置所选窗口的状态为暂停。

OnCustomerArrive 将一个新顾客添加到队列中,而 OnCustomerLeave 则在服务后从队列中移除顾客。

总的来说,该代码提供了一个管理窗口队列系统的基本框架,但可以通过扩展以处理更高级的功能,例如为顾客计算等待时间或向员工或经理提供实时状态更新。

求最佳答案{:10_254:}

Sirenarya 发表于 2023-6-7 11:03:34

isdkz 发表于 2023-6-6 20:18
这个程序是一个窗口排队管理系统,主要使用了链表数据结构来存储和操作每个窗口的信息。下面是一些代码中主 ...

我想问问那我怎么在这里面加入这个功能呢,统计分析功能:
(1)可统计当前排队人数最多的窗口业务类型,为新增窗口提供依据;(2)可按评分高低顺序展示所有窗口;(3)可按服务的顾客总数顺序展示所有窗口:

isdkz 发表于 2023-6-7 11:05:17

Sirenarya 发表于 2023-6-7 11:03
我想问问那我怎么在这里面加入这个功能呢,统计分析功能:
(1)可统计当前排队人数最多的窗口业务类型, ...

为了实现你所说的功能,需要在你的代码中添加一些函数,并修改一些已存在的函数。下面是这些函数的基本思路和实现:

1. 统计当前排号人数最多的窗口业务类型:

你可以创建一个函数,遍历整个窗口列表,然后找到排队人数最多的窗口业务类型。这个函数可能类似于以下:

void getMaxQueueType() {
    if (WL == NULL) {
      printf("No windows available.\n");
      return;
    }
    int maxQueue = -1;
    WindowType maxType;
    WinList P = WL;
    while (P != NULL) {
      if (P->data.people > maxQueue) {
            maxQueue = P->data.people;
            maxType = P->data.type;
      }
      P = P->next;
    }
    printf("Max queue type: %d with %d customers in queue\n", maxType, maxQueue);
}


2. 按照评分高低顺序展示所有窗口:

你可以使用一个排序算法(例如:冒泡排序,选择排序等)来对窗口列表进行排序,然后再遍历列表进行展示。但是,链表的排序操作相对复杂,你可能需要重新组织链表的结构。在这里,你可能需要创建一个新的数据结构(例如:数组)来存储评分和窗口的映射,然后对数组进行排序。

3. 按服务的顾客总数顺序展示所有窗口:

这个功能的实现方式类似于按评分排序。你可以创建一个新的数据结构(例如:数组)来存储服务顾客总数和窗口的映射,然后对数组进行排序。

这些功能的具体实现取决于你对系统的需求。你可能需要根据你的具体需求进行修改和扩展。在实际编程中,你需要测试和调试你的代码,以确保新添加的功能能够正确运行。

Sirenarya 发表于 2023-6-7 11:37:29

isdkz 发表于 2023-6-7 11:05
为了实现你所说的功能,需要在你的代码中添加一些函数,并修改一些已存在的函数。下面是这些函数的基本思 ...

好的呢,谢谢你
页: [1]
查看完整版本: 新手,想知道这个代码怎么分析