All things are difficult before they are easy. 没有软件的裸机是一具僵尸,没有硬件的软件是一个幽灵。2012,专注于Linux和C语言,关注自动化、性能测试,关注开源社区和开源测试工具、方法,尝试测试团队管理!

浅析C中的回调函数

上一篇 / 下一篇  2010-12-20 23:21:48 / 个人分类:C/C++

前阵子在看李先静的《系统程序员成长计划》,看到里面里面说到了回调函数这个概念,不过似乎没记得特别清楚。也提到函数指针是实现多态的一个手段,多态是隔离变化的一个秘诀。下面还是简单说一下回调函数吧。
1.什么是回调函数?
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
概括起来,回调机制包括两部分:服务执行者和服务方式制定者。
    1.服务执行者先制定服务规范;
    2.服务方式制定者然后按照规范制定服务方式;
    3.然后执行者按照这个方式提供服务。
回调函数的方式是把函数指针的作为参数传递进去,所以规范就是约定函数的参数类型、个数。
被调用者回头调用调用者的函数(有点拗口),故称其为回调(callback)
2.一个非常经典的回调函数例子
其实C的标准库中就有回调函数最经典的实例,C的”stdlib”中声明的qsort函数(快速排序),用来对数值进行排序。显然,顺序还是降序,元素谁大谁小这些问题,库程序员在编写qsort的时候不可能决定。这些问题是要在用户调用这个函数的时候才能够决定。那边qsort如何保证通用性和灵活性呢?采用的办法是让函数的使用者来制定排序规则。
qsort的声明如下:
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );其中int ( * comparator ) ( const void *, const void * )便是一个函数指针,指向某个用户自定义的比较函数(就是一个回调函数经典实例)。
一个简单的使用例子:
#include <stdio.h>

int values[] = { 40, 10, 100, 90, 20, 25 };
 
int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}
 
int main ()
{
  int n;
  qsort (values, 6, sizeof(int), compare);
  for (n=0;n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}

3.回调函数的其他例子
书中,举的一个例子:实现一个打印双向链表的函数dlist_print,但该函数并不知道,双向链表中所存放的数据类型所以不知道printf这个到底怎么写,这里它可以让调用方提供一个回调函数print来打印一个链表中的数据。dilist_priint的实现如下:
DListerRet dlist_print(Dlist * thiz, DlistDataPrintFunc print)
{
    DListRet ret = DLIST_RET_OK;
    DlistNode* iter = thiz->first;
    while(iter != NULL)
    {
        print(iter->data);
        iter = iter->next;
    }
    return ret;
}
调用方自己实现print_int这样的回调函数。
回调可用于通知机制,例如,有时要在程序中设置一个计时器,每到一定时间,程序会得到相应的通知,但通知机制的实现者对我们的程序一无所知。而此时,就需有一个特定原型的函数指针,用这个指针来进行回调,来通知我们的程序事件已经发生。

参考资料:
http://blog.csdn.net/general1982/archive/2008/12/30/3649583.aspx
http://hi.baidu.com/spidermanzy/blog/item/b25b00956469c6097bf48016.html

相关阅读:

TAG: 回调函数 函数指针

 

评分:0

我来说两句

smile665

smile665

Stay hungry, stay foolish. 得意之时谨记,一半命运还掌握在上帝手里;失意之时须知,一半命运还掌握在自己手里。

日历

« 2024-04-24  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 955669
  • 日志数: 220
  • 建立时间: 2008-11-06
  • 更新时间: 2012-10-06

RSS订阅

Open Toolbar