1.首先我们要明确什么是回调函数以及其在什么时候被使用:
如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数,回调函数不是实现该函数的软件模块直接调用,而是在特定的事件或条件发生时由另外的软件模块通过函数指针的方式调用,用于对该事件或条件进行响应,
其工作机制一般如下所示:
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
回调函数的作用:
⑴函数与函数之间的解耦
⑵回调函数可以把调用者与被调用者分开,所以调用者不关心谁是被调用者
其可以大大提示编程的效率,同时,有一些需求必须要使用回调函数来实现
2.对于lab5.2其文件结构为:linktableInternal.h被linktable.h引用,linktable.h被linktable.c引用,linktable.c被menu.c引用
linktableinternal.h:申明了两个结构体LinkTable和LinkTableNode。LinkTable结构体是链表;LinkTableNode是链表结点,指向下一个链表指针的节点。
linktable.h:引用linktableinternal.h,定义了结构体tLinkTableNode,tLinkTable,并且在该文件中定义了上述两个结构体的创建链表、删除链表、添加链表节点、删除链表节点、查找链表节点、获取链表头结点、获取链表尾结点。
linktable.c:引用linktable.h,对linktable.h中的定义进行了具体的实现
menu.c:引用linktable.c,LinkTable链表中的节点是与业务无关的,数据与业务分离,实现功能
Callback函数需要一个Call-in函数,在这个例子里的接口定义如下
/*
* Search a LinkTableNode from LinkTable
* int Conditon(tLinkTableNode * pNode, void * args);
*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args);
其中放在参数位置的函数Condition允许用户自定义,通过这个办法实现了用户自定义查询条件,以在链表中查询结点的功能,在linktable.c中通过如下代码做到这一点:
/*
* Search a LinkTableNode from LinkTable
* int Condition(tLinkTableNode * pNode, void * args);
*/
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable,
int Condition(tLinkTableNode * 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;
}
并在findCmd函数中用到了这个“在链表中按照给定查询条件查询结点”的功能:
/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
return (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)cmd);
}
概括一下“查找cmd链表”这个功能体现的接口设计分层:
linktableInternal.h基本链表结构
linktable.h定义链表需要实现的函数,在这一层定义了call-in、callback函数的接口
linktable.c实现链表函数和call-in函数(定义它根据callback函数的情况如何做出反应)
menu.c使用链表函数,并定义callback函数
作者尾号后三位:114