工程化编程实战callback接口学习

warning

增加头文件

#include<string.h>

bug

输入quit命令,并没有执行退出

循环的结束条件不对

while(pNode != pLinkTable->pTail)//当遍历最后一个节点时,退出了循环体,没有对链表最后一个节点进行判断
    {    
        if(Conditon(pNode) == SUCCESS)
        {
            return pNode;				    
        }
        pNode = pNode->pNext;
    }
return NULL;

debug

step1:修改循环条件

while(pNode != NULL)

step2:显示的将malloc分配的空间初始化,避免出错。

int InitMenuData(tLinkTable ** ppLinktable)
{
    *ppLinktable = CreateLinkTable();
    tDataNode* pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->pNext = NULL;//显示的初始化
    pNode->cmd = "help";
    pNode->desc = "Menu List:";
    pNode->handler = Help;
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
    pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->pNext = NULL;//显示的初始化
    pNode->cmd = "version";
    pNode->desc = "Menu Program V1.0";
    pNode->handler = NULL; 
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
    pNode = (tDataNode*)malloc(sizeof(tDataNode));
    pNode->pNext = NULL;//显示的初始化
    pNode->cmd = "quit";
    pNode->desc = "Quit from Menu Program V1.0";
    pNode->handler = Quit; 
    AddLinkTableNode(*ppLinktable,(tLinkTableNode *)pNode);
    return 0; 
}

回调函数的作用机制

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数 。

涉及三个函数

起始函数:调用者

tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition);
}

中间函数:枢纽

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode))

回调函数:执行者

SearchCondition(tLinkTableNode * pLinkTableNode)

回调函数的优势

因为回调函数像参数一样传入中间函数。那么在传入一个回调函数之前,中间函数是不完整的。换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为,所以根据不同条件可以触发不同的回调函数,是的程序更加具有灵活性,类似与c++多态机制。

回调方式

阻塞式回调和延迟式回调。

阻塞式回调里,回调函数的调用一定发生在起始函数返回之前;而延迟式回调里,回调函数的调用有可能是在起始函数返回之后。

原文地址:https://www.cnblogs.com/Alexkk/p/12525517.html