高级软件工程 回调函数

回调函数(callback函数)

  • 1.函数的名字可作为参数。
  • 2.函数名作为参数传递给其他函数。

作用:

  • 1.恰当时机发通知

  • 2.让程序设计更加灵活

  • 3.提高效率

编译运行:

  • 使用gcc

    cd xxx/lab4   
    gcc menu.c linktable.c -o menu -lpthread	# lab5.1 5.2同样可以使用这个命令
    
  • 配置launch.json和task.json

    其中launch.json的配置与作业3一样,修改task.json如下即可:

    {
        "tasks": [
            {
                "type": "cppbuild",
                "label": "C/C++: gcc.exe",
                "command": "C:\\MinGW64\\bin\\gcc.exe",
                "args": [
                    "menu.c",
                    "linktable.c",
                    "-o",
                    "${fileDirname}\\menu.exe",
                    "-lpthread"
                ],
                "options": {
                    "cwd": "${fileDirname}"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "detail": "调试器生成的任务。"
            }
        ],
        "version": "2.0.0"
    
    

lab4

共定义四个结构体

typedef struct LinkTableNode
{
    struct LinkTableNode * pNext;
} tLinkTableNode;
typedef struct LinkTable
{
    tLinkTableNode *pHead;
    tLinkTableNode *pTail;
    int			SumOfNode;
    pthread_mutex_t mutex;
} tLinkTable;
typedef struct DataNode
{
    tLinkTableNode * pNext;
    char*   cmd;
    char*   desc;
    int     (*handler)();
} tDataNode;
typedef struct Node
{
    tLinkTableNode * pNext;
    int data;
} tNode;

​ 类似于c++继承的关系,后三种结构体作为第一种结构体的子类,利用强制类型转换即可实现父类和子类的转换。当我们需要使用链表操作时,可以使用强制转换将子类型转成父类型。在找到链表中的结点后,可以再次强制转换成子类型,进而用c语言实现了多态。

lab5.1

编译运行

​ lab5.1较lab4最大的不同是实现了回调函数,主要体现在以下几个函数:

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;
}
int SearchCondition(tLinkTableNode * pLinkTableNode)
{
    tDataNode * pNode = (tDataNode *)pLinkTableNode;
    if(strcmp(pNode->cmd, cmd) == 0)
    {
        return  SUCCESS;  
    }
    return FAILURE;	       
}
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition);
}

​ 在Findcmd函数中用了searchCondition函数名作为参数,而searchConditon函数的功能是判断结点成员是否与cmd相同,SearchLinkTableNode巧妙利用了这个函数实现了在链表中查询结点的需求。如果我们要修改查询条件,只需要改变Conditon函数中的内容即可,提高了接口的通用性。

lab5.2

编译运行:

​ lab5.1与lab5.2在以下几个函数的声明

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void * args), void * args)
int SearchCondition(tLinkTableNode * pLinkTableNode, void * args)
tDataNode* FindCmd(tLinkTable * head, char * cmd)
{
    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition,(void*)cmd);
}

​ 与lab5.1将cmd作为全局变量,这里将cmd作为参数传递给函数,实现了FindCmd的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值