回调函数

  今天看到回调函数,有点迷糊,找了好多搜索引擎的资料,都不是让我很能理解,看了《c和指针》我才明白了。

简单描述一下什么是回调函数:

  用户把一个函数指针作为参数传递给其他函数,后者将“回调”用户的函数。如果函数可以再不同的时间执行不同类型的工作或者执行只能由函数调用者定义的工作,都可以使用回调函数。 回调函数无法知道比较的值的类型,所以参数的类型被声明为void*。表示一个指向未知类型的指针。 可以通过函数指针来实现回调函数。一个指向回调函数的指针作为参数传递给另一个函数,后者使用这个指针调用回调函数。

  可能说了太多也不会很是明白,来几个事例说说。

  当我们在在链表中查找一个数时,我们一般会这样写:
  

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

    return node;
}

这样就限制我们只能在查找的数必须是int类型,当变为其他类型时我们就无法用这个函数,但是重新写一个函数,他们重复代码又太多。那我们看看用回调函数如何办到。  

回调函数查找:

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

 这样利用回调函数就可以解决如上问题。我们把一个函数指针( int (compare)(void const , void const *) )作为参数传递给查找函数,查找函数将“回调”比较函数。当我们需要执行不同类型的比较时我们合理调用该函数。例如:当我们整形查找时: search_list( root, &desired_value, compare_int ); ,使用字符查找时: search_list( root, &desired_value, compare_char ); 。这就是回调函数简单的应用,当然回调函数不仅仅只是用于这些简单的例子,比如库函数qsort就是利用回调函数实现。
  函数原型如下:
  

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

为了更好地理解回调函数,接下来我们来写一个自己的qsort函数(利用冒泡排序)

int char_compare(void const * c1,void const* c2) //比较函数
{
    int a = *((int*)c1);
    int b = *((int*)c2);
    return a>b ? 1 : a<b ? -1 : 0;
}

void Swap(char *str1,char *str2,int size) 
{
    while (size--)
    {
        char tmp = *str1;
        *str1 = *str2;
        *str2 = tmp;
        str1++;str2++;
    }
}
void MyQsort(void *str,int len,int elen,int(*compare)(void const*,void const*))  //基于回调函数写的排序算法
{
    int i = 0;
    int j = 0;
    int flag = 1;
    for (i=0; i<len-1; i++)
    {
        for (j=0; j<len-1-i; j++)
        {
            if (compare((char*)str+j*elen,(char*)str+(j+1)*elen)>0)
            {
                flag = 0;
                Swap((char*)str+j*elen,(char*)str+(j+1)*elen,elen);
            }
        }
        if (flag)
            return;
    }
}

简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我 们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
回调函数实现的机制是:

  (1)定义一个回调函数;

  (2)提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;

  (3)当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
  看了两个例子大家应该能理解回调函数了,如果还有什么问题可以私信我,建议把指针这节理解透彻,这是指针的扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙跃十二

写的不错,给点鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值