Chinaunix首页 | 论坛 | 博客
  • 博客访问: 621223
  • 博文数量: 172
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 1252
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-29 22:26
文章分类

全部博文(172)

文章存档

2011年(6)

2010年(7)

2009年(159)

我的朋友

分类: LINUX

2009-09-15 20:58:37

回调函数:

如果参数是一个函数指针,调用者可以传递一个函数的地址给实现者,让实现者去调用它,这称为回调函数(Callback Function)。

回调机制包括两部分:服务执行者和服务方式制定者。
             1. 
服务执行者先制定服务规范;
             2.
服务方式制定者然后按照规范制定服务方式;
             3.
然后执行者按照这个方式提供服务。
回调函数的方式是把函数指针的作为参数传递进去,所以规范就是约定函数的参数类型,个数。

以下是一个简单的例子。实现了一个repeat_three_times函数,可以把调用者传来的任何回调函数连续执行三次。

 

/* callback.h */
#ifndef CALLBACK_H
#define CALLBACK_H

typedef void (*callback_t)(void *);
extern void repeat_three_times(callback_t, void *);

#endif

/* callback.c */
#include "callback.h"

void repeat_three_times(callback_t f, void *para)
{
     f(para);
     f(para);
     f(para);
}

/* main.c */
#include <stdio.h>
#include "callback.h"

void say_hello(void *str)
{
     printf("Hello %s\n", (const char *)str);
}

void count_numbers(void *num)
{
     int i;
     for(i=1; i<=(int)num; i++)
     printf("%d ", i);
     putchar('\n');
}

int main(void)
{
     repeat_three_times(say_hello, "Guys");
     repeat_three_times(count_numbers, (void *)4);
     return 0;
}

 

回调函数的一个典型应用就是实现类似C++的泛型算法(Generics Algorithm)。

下面实现的max函数可以在任意一组对象中找出最大值,可以是一组int、一组char或者一组结构体,但是实现者并不知道怎样去比较两个对象的大小,调用者需要提供一个做比较操作的回调函数。还有经典的例子就是排序函数

 

/* generics.h */
#ifndef GENERICS_H
#define GENERICS_H

typedef int (*cmp_t)(void *, void *);
extern void *max(void *data[], int num, cmp_t cmp);

#endif
/* generics.c */
#include "generics.h"

void *max(void *data[], int num, cmp_t cmp)
{
     int i;
     void *temp = data[0];
     for(i=1; i<num; i++) {
     if(cmp(temp, data[i])<0)
     temp = data[i];
     }
     return temp;
}
/* main.c */
#include <stdio.h>
#include "generics.h"

typedef struct {
     const char *name;
     int score;
} student_t;

int cmp_student(void *a, void *b)
{
     if(((student_t *)a)->score > ((student_t *)b)->score)
     return 1;
     else if(((student_t *)a)->score == ((student_t *)b)->score)
     return 0;
     else
     return -1;
}

int main(void)
{
     student_t list[4] = {{"Tom", 68}, {"Jerry", 72},
         {"Moby", 60}, {"Kirby", 89}};
     student_t *plist[4] = {&list[0], &list[1], &list[2], &list[3]};
     student_t *pmax = max((void **)plist, 4, cmp_student);
     printf("%s gets the highest score %d\n", pmax->name, pmax->score);

     return 0;
}

阅读(2165) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~