一、实验目标
1.给lab5-1.tar.gz(在实验楼Linux虚拟机环境下~/se_files/目录下)找bug,quit命令无法运行的bug
2.利用callback函数参数使Linktable的查询接口更加通用
3.隐藏LinkTable的内容
二、实验步骤
第一步是改BUG,示例程序中quit命令不能正常使用。
首先,观察代码可知,一共三个命令help,version,quit,他们从定义到初始化都是使用相同的代码结构,尤其是help和quit,都调用了外部函数,但是help能正常使用,quit却不能。
其次,我首先尝试在初始化时将quit命令与help命令调换顺序,即将本来置于链表末尾的quit命令置于链表头部,而help置于链表尾部。保存编译运行,quit命令能够正常使用!但是help命令不能。
再次,我觉得已经找到了问题的关键,那就是链表尾节点的遍历有问题,为了进一步验证我的猜想,我在init函数中又新增了一个nouse命令置于链表尾部,保存编译运行,果然不出我所料,前三个命令都能正常使用,最后一个却不行。
然后,既然找到了问题是SearchLinkTableNode函数的遍历有BUG导致的,接下来自然是去linktable.c文件中修改,修改代码如下:
while(pNode != NULL)
第二步是使callback函数的接口更通用
以下是三个文件中修改的代码
linktable.h
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Condition(tLi
nkTableNode *pNode, void * args), void * args);
linktable.c
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Condition(tLi
nkTableNode *pNode, void * args), void * args)
{
if(pLinkTable == NULL || Condition == NULL)
{
return NULL;
}
tLinkTableNode * pNode = pLinkTable->pHead;
while(pNode != NULL)
{
if(Condition(pNode, args) == SUCCESS)
{
return pNode;
}
pNode = pNode->pNext;
}
return NULL;
}
menu.c
int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
{
char * cmd = (char *)args;
tDataNode * pNode = (tDataNode *)pLinkTableNode;
if(strcmp(pNode->cmd, cmd) == 0)
{
return SUCCESS;
}
return FAILURE;
}
tDataNode* FindCmd(tLinkTable *pLinkTable, char *cmd)
{
return (tDataNode *)SearchLinkTableNode(pLinkTable, SearchCondition, cmd);
}
第三部是在linktable.h中隐藏结构体LinkTable的内容
具体代码如下
linktable.h
typedef struct LinkTable tLinkTable;
linktable.c
typedef struct LinkTable
{
tLinkTableNode * pHead;
tLinkTableNode * pTail;
intSumOfNode;
}tLinkTable;
三、实验心得
本次试验,通过找BUG,修改通用接口等方式学习了callback函数的使用方法,发现自己在完成代码的过程中,还是存在各种不良的习惯。以后要多动手,多总结,培养良好的代码习惯。