|
函数指针的两个常见用法是,一是做为结构成员,做面向对向的封装,另一个就是回调函数的设计。
所谓回调函数,也就是把函数传递给另一个函数,另一个函数在某一时候调用这个函数。
测试代码:
#include <stdio.h>
int add (int a, int b)
{
return (a + b);
}
int do_it(int (*ADD)(int, int), int a, int b)
{
printf ("%d\n", ADD (a, b));
return 0;
}
int main (int argc, char **argv)
{
int a = 3;
int b = 4;
do_it(add, a, b);
return 0;
} 输出结果为 7。
进一步抽象,有下面的代码:
#include <stdio.h>
typedef int (*ADD) (int a, int b);
int add (int a, int b)
{
return (a + b);
}
int sub (int e, int f)
{
return (f - e);
}
int do_it(ADD func, int a, int b)
{
printf ("%d\n", func (a, b));
return 0;
}
int main (int argc, char **argv)
{
int a = 3;
int b = 4;
ADD add_p = add;
ADD sub_p = sub;
do_it (sub, a, b);
do_it (add, b, a);
do_it (add_p, a, b);
do_it (sub_p, a, b);
return 0;
} 运行与输出:beyes@linux-beyes:~/C> ./call_back.exe
1
7
7
1 上面,定义了一个函数指针 ADD 类型,这个函数指针指向的是一个含有两个整型参数,返回值也为整型的函数,而不管所指向的函数内部如何实现。
小结:
软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等到对方执行完毕才返回,它是一种单向调用;回调,是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。三者调用如下图所示:
回调函数可以象普通函数一样被程序调用,但是只有它被当作参数传递给被调函数时才能称作回调函数。
在测试程序2里看到,如果赋了不同的值给该参数,那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。 |
|