作业3:深入理解Callback函数

Callback函数的工作机制

在程序设计中,Callback函数是一种常用的技术,它指的是在一个函数中调用另外一个函数,并将其作为参数传递给该函数。Callback函数的作用是将程序的控制权交给调用者,使得调用者可以在某个特定的时刻执行自己的代码。

Callback函数的工作机制是由调用者来决定的。调用者将一个函数指针作为参数传递给被调用者,被调用者在需要时调用该函数指针,从而将程序的控制权交回给调用者。这样,调用者就可以在被调用者执行完毕后继续执行自己的代码。

internal是内部的意思,linktableInternal.h被linktable.h引用,linktable.h被linktable.c引用,linktable.c被menu.c引用。

linktableInternal.h:linkTable结构体是链表,包含链表头、尾结点,以及一个int型存储链表中节点值之和,还有一个互斥变量mutex;文件里也定义了链表结点结构体LinkTableNode,这里只声明要有最基本的属性即指向下一个LinkTableNode的指针pNext。

linktable.h:由linkTable和LinkTableNode定义新结构体tLinkTableNode和tLinkTable,这个文件里基于这两个新结构体规定了要实现的链表应该实现哪些方法,包括删除链表、添加结点、删除结点、查抄结点、获取头、尾结点。如果希望链表实现另一套方法,可以仿照linktable.h包含linktableInternal.h,写另一套接口。

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);
}

FindCmd调用SearchCondition,要把自己的参数传给后者,可以选择①不给SearchLinkTableNode及其接口Condition加参数,声明一个全局变量,随用随赋值;②增加参数,在FindCmd函数体里把cmd链表指针传给SearchLinkTableNode。
 

根据如下集中耦合定义,①属于公共耦合,两个函数通过公共可访问的变量协作;②属于标记耦合,虽然显式传递的不是基本数据类型而是指针,但耦合度也比公共耦合低。

公共耦合

  • 当软件模块之间共享数据区或变量名的软件模块之间即是公共耦合,显然两个软件模块之间的接口定义不是通过显式的调用方式,而是隐式的共享了共享了数据区或变量名。

数据耦合

  • 在软件模块之间仅通过显式的调用传递基本数据类型即为数据耦合。

标记耦合

  • 在软件模块之间仅通过显式的调用传递复杂的数据结构(结构化数据)即为标记耦合,这时数据的结构成为调用双方软件模块隐含的规格约定,因此耦合度要比数据耦合高。但相比公共耦合没有经过显式的调用传递数据的方式耦合度要低。
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
std::thread是C++标准库中的一个类,用于创建和管理线程。它提供了一种方式来并发地执行代码,允许在程序中同时执行多个任务。 在提供的引用内容中,有一个名为callback_test的函数,它使用std::thread来创建了一个工作线程(worker_thread_),并在该线程中调用了OnMdJamin函数。 在JaminImpl类的定义中,有一个名为GetJaminData的成员函数,它使用了一个函数指针类型CallFun作为参数,并在内部调用了该函数指针指向的函数。 根据引用内容中的代码,我们可以推断出std::thread callback指的是在std::thread对象中注册一个回调函数。具体来说,它可能是在创建std::thread对象时指定一个函数或者使用成员函数指针作为参数,以便在线程执行时调用该函数。这种方式可以用来实现回调机制,使得线程在某些条件满足时调用指定的回调函数。但是,具体的回调函数的实现和调用逻辑需要根据实际代码进行进一步分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++中回调函数CallBack)](https://blog.csdn.net/jamin_liu_90/article/details/119747152)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值