[高级软件工程实验]用callback增强链表模块来实现命令行菜单小程序V2.8

版本库URL:https://github.com/swagnhen/Advanced-Software-Engineering-Exercise.git

实验要求

1)给lab5-1.tar.gz找bug,quit命令无法运行的bug
2)利用callback函数参数使Linktable的查询接口更加通用
3)注意接口的信息隐藏

实验内容

代码查错

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))
{
    if(pLinkTable == NULL || Conditon == NULL)
    {
        return NULL;
    }
    tLinkTableNode * pNode = pLinkTable->pHead;
    while(pNode != pLinkTable->pTail) //此处出错,判断条件应为pNode!=NULL
    {    
        if(Conditon(pNode) == SUCCESS)
        {
            return pNode;                   
        }
        pNode = pNode->pNext;
    }
    return NULL;
}

方法SearchLinkTableNode中循环判断pNode是否满足Condition的跳出条件出错,原写法中是判断->处理->下一节点的逻辑,这样以pLinkTable->pTail作为结束条件的话就会失去对最后一个节点的处理,即quit指令出错。

callback增强链表模块

callback增强可重用链表实现包含于linkedlist.h与linkedlist.c中
shell中各命令功能的实现包含在cmdopt.h与cmdopt.c中
main函数包含于shelllet.c中

通过gcc编译时请使用命令

gcc linkedlist.c cmdopt.c shelllet.c -o shelllet

callback增强可重用链表设计

typedef struct Node
{
    struct Node *next;
} Node;

typedef struct LinkedList
{
    Node *head;
    Node *tail;
    int len;
} LinkedList;

LinkedList *initLinkedList();

int delLinkedList(LinkedList *l);

int addNode(LinkedList *l, Node *n);

int delNode(LinkedList *l, Node *n);

//callback增强接口,参数key用于比对,不需要时可置NULL
Node *searchNode(LinkedList *l, char* key, int operation(Node *n, char* key));

Node *getHeadNode(LinkedList *l);

Node *getNextNode(LinkedList *l, Node *n);

功能指令链表节点设计

typedef struct CmdNode
{
    Node *next;
    char *cmd;
    int (*handler)();
} CmdNode;

int initMenuData(LinkedList **l);

//用于被searchNode调用
int searchOperation(Node * n, char* cmd);

CmdNode *findCmd(LinkedList *head, char *cmd);

具体实现

searchNode

Node *searchNode(LinkedList *l, char *key, int operation(Node *n, char *key))
{
    if (l == NULL && operation == NULL)
    {
        return NULL;
    }
    Node *n = l->head;
    while (n != NULL)
    {
        if (operation(n, key) == 0)
        {
            return n;
        }
        n = n->next;
    }
    return NULL;
}

searchOperation

int searchOperation(Node *n, char *cmd)
{
    CmdNode *p = (CmdNode *)n;
    if (strcmp(p->cmd, cmd) == 0)
    {
        return 0;
    }
    return -1;
}

findCmd

CmdNode *findCmd(LinkedList *l, char *cmd)
{
    return (CmdNode *)searchNode(l, cmd, searchOperation);
}

运行效果
这里写图片描述

实验问题与总结

视频一开始说为了信息屏蔽和更方便别的程序员使用才引入的callback,然后为了传参加入了一个全局变量cmd就感觉不太好
于是在searchNode里加了一个key字段用于比较,不过写到这里的时候我觉得void*类型可能更合适,毕竟调用者是知道用于比较的对象是什么类型的,当然一般来讲的话就是字符串或者数字,数字的话用atoi函数转换一下就可以了

【Swegnhan + 《软件工程(C编码实践篇)》MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值