版本库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】