回调函数


案例一:

有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)

叫醒(对象,….,叫醒方式);

案例二:

我们对链表的查找,一般会这样写 

Node *search_list( Node *node, int const value )
  {
     
while ( NULL != node ){
          if ( node->value == value ){
              break;
         }
          node = node->link;
      }
    
return node;
 }

(这里不要较真 有人会接的我把int const 改成type  然后再在上面定义type的类型  这样修改就方便了)

但是分析上面的代码我们发现  该程序只能查找int类型的,如果程序突然改变需要使用到char型 则程序就的修改这样很不利于开发,而且也会给增加程序冗余。

最好的方法是我们依然使用这样的代码 但是不去确定value的类型 其类型有第三方(回调函数)来告诉我们具体的类型。

 

 

使用回调函数查找:

int compare_int( void const *a, void const *b )
{

     if ( *( int * )a == *( int * )b ){
        return 0;
     }
   
return 1;
}

 

Node *search_list(Node *node, void const *value,

  int (*compare)(void const *, void const *))  //函数指针
 {
      while(node != NULL){
         if(compare(&node->value, value) == 0//相等
            break;
         node = node->link;
    }
     
return node;
}

这样就可以利用回调函数实现上面的问题了。

案例三:

库函数 以及sort函数都是用了回调函数的思想

void qsort(
  
void *base,    //字符串首地址
   size_t num,  //排序总个数
   size_t width, //排序元素的大小
  
int (__cdecl *compare )(const void *, const void *)  //函数指针
);

总结:

回调并不是“你我”两方的互动,而是ABC的三方联动。有了这个清楚的概念,在自己的代码里实现回调时才不容易混淆出错。

 

 

 

 

另外,回调实际上有两种:阻塞式回调和延迟式回调。两者的区别在于:阻塞式回调里,回调函数的调用一定发生在起始函数返回之前;而延迟式回调里,回调函数的调用有可能是在起始函数返回之后。

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值