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

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

1. 运行程序,得到如下结果:

可以看出除了quit命令,其他的都可以正常执行,那么我们需要通过debug进入到main函数中接收指令函数中查看

2.设置断点,debug程序

PS C:Users91926Desktop高级软件工程lab5.1> gcc -g linktable.c menu.c -o menu
PS C:Users91926Desktop高级软件工程lab5.1> gdb menu
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from menu...done.
(gdb) break 111
Breakpoint 1 at 0x401b72: file menu.c, line 111.
(gdb) run
Starting program: C:Users91926Desktop\lab5.1menu.exe
[New Thread 23380.0x6438]
[New Thread 23380.0x4c88]
[New Thread 23380.0x65e4]
Input a cmd number > quit

Thread 1 hit Breakpoint 1, main () at menu.c:111
111             tDataNode *p = FindCmd(head, cmd);
(gdb) s
FindCmd (head=0xed1810, cmd=0x408980 <cmd> "quit") at menu.c:61
61          return  (tDataNode*)SearchLinkTableNode(head,SearchCondition);
(gdb) s
SearchLinkTableNode (pLinkTable=0xed1810, Conditon=0x401960 <SearchCondition>) at linktable.c:144
144         if(pLinkTable == NULL || Conditon == NULL)
(gdb) n
148         tLinkTableNode * pNode = pLinkTable->pHead;
(gdb) n
149         while(pNode != pLinkTable->pTail)
(gdb) n
151             if(Conditon(pNode) == SUCCESS)
(gdb) n
155             pNode = pNode->pNext;
(gdb) n
149         while(pNode != pLinkTable->pTail)
(gdb) n
151             if(Conditon(pNode) == SUCCESS)
(gdb) n
155             pNode = pNode->pNext;
(gdb) n
149         while(pNode != pLinkTable->pTail)
(gdb) n
157         return NULL;

可以看出,返回了NULL

3.我们分析出,是函数SearchLinkTableNode出了问题,进入函数体我们可以看到:

tLinkTableNode *SearchLinkTableNode(tLinkTable *pLinkTable, int (*Conditon)(tLinkTableNode *pNode))
{
    if(pLinkTable == NULL || Conditon == NULL)
    {
        return NULL;
    }
    tLinkTableNode *pNode = pLinkTable->pHead;
    while(pNode != pLinkTable->pTail)
    {    
        if(Conditon(pNode) == SUCCESS)
        {
            return pNode;                   
        }
        pNode = pNode->pNext;
    }
    return NULL;
}

我们已知quit是链表的最后一个节点,再看while循环终止条件,若当前不在最后一个结点,则进入循环内部,所以,我们输入quit根本进入不了循环里面

所以我们将循环条件修改如下:

while(pNode != NULL)

最终程序运行成功:

4. 回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。使用方法首先定义回调函数,然后实现方在初始化的时候将函数指针注册给调用者,当程序运行时,调用者通过函数指针调用回调函数。

原文地址:https://www.cnblogs.com/htc524/p/12513244.html