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

  • 在VSCode下编译运行lab5-1

  • 运行代码时发现输入quit命令后,显示“This is a wrong cmd!”
  • 通过VSCode+GDB调试程序找出quit命令无法运行的bug产生的原因

  • int main()
    {
        InitMenuData(&head); 
       /* cmd line begins */
        while(1)
        {
            printf("Input a cmd number > ");
            scanf("%s", cmd);
            tDataNode *p = FindCmd(head, cmd);
            if( p == NULL)
            {
                printf("This is a wrong cmd!\n ");
                continue;
            }
            printf("%s - %s\n", p->cmd, p->desc); 
            if(p->handler != NULL) 
            { 
                p->handler();
            }
       
        }
    }
    

     

  • 发现bug后,通过查看main函数代码,发现问题出在FindCmd()函数,此函数的功能为搜索匹配的cmd,显然其未能成功搜索到quit命令。根据InitMenuData()函数初始化命令的时候,将quit命令放在链表的末尾,根据经验可以猜测链表末尾未与输入的cmd匹配。
  • 下面使用gbd调试来具体分析代码
  • 进入调试后使用l输入list查看代码,在FindCmd()函数那一行打上断点,执行代码
  • 发现进入FindCmd函数后,会进而执行SearchLinkTableNode()函数,进入while循环中,,通过Conditon()函数判断链表结点中的cmd与输入的cmd是否相等。这里condition()函数是一个参数,具体的实现由SearchConditon()完成。while循环执行两次便不满足循环条件了,返回NULL。可见while循环少了一次。
  • 分析while循环的条件,pNode!=pLinkTable->pTail,因为quit命令所在的结点刚好就是链表的pTail结点,所以该结点被排除在外。我们可以通过修改while循环的条件为pNode!=NULL来排除此bug。
  • 分析callback接口的运行机制,总结callback接口设计的方法
  • 一般情况下,应用程序会时常通过API调用库里预先准备好的函数,但是有些库函数却要求应用先传给它一个函数,好在合适的时候的调用,以完成目标任务,这个被传入的、后又被调用的函数就称为回调函数。
  • 对于lab5-1中,SearchCondition()就是回调函数。作为库函数的SearchLinkTableNode()函数,需要先传入一个Condition()函数才会得以执行。Condition用于比较某个链表结点中的cmd是否与输入的cmd相同。使用这样的回调函数,就可以不用保持库函数中链表的结构、变量名称与我们创建的链表结构、变量名称一致。使库函数的应用更加灵活,降低了耦合性。
posted @ 2020-03-19 18:16  zhouxinghui  阅读(166)  评论(0编辑  收藏  举报