函数指针与回调函数

什么是函数指针?举个例子:int (*func)();就是一个函数指针,指向的函数为空参数,返回整型;

什么是一个回调函数?回调函数是一个程序员不能显式调用的函数;而是通过将回调函数的地址传给被调用者从而实现调用。回调函数是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

void f(); // 函数原型

上面的语句声明了一个函数,没有输入参数并返回void。那么函数指针的声明方法如下:void (*) ();
让我们来分析一下,左边圆括弧中的星号是函数指针声明的关键。另外两个元素是函数的返回类型(void)和由边圆括弧中的入口参数(本例中参数是空)。注意本例中还没有创建指针变量,只是声明了变量类型。目前可以用这个变量类型来创建类型定义名及用sizeof表达式获得函数指针的大小:
unsigned psize = sizeof (void (*) ()); // 获得函数指针的大小
typedef void (*pfv) (); // 为函数指针声明类型定义

pfv是一个函数指针,它指向的函数没有输入参数,返回类行为void。使用这个类型定义名可以隐藏复杂的函数指针语法。
指针变量应该有一个变量名:void (*p) ();  //p是指向某函数的指针。p是指向某函数的指针,该函数无输入参数,返回值的类型为void。左边圆括弧里星号后的就是指针变量名。有了指针变量便可以赋值,值的内容是署名匹配的函数名和返回类型。例如:

void func()
{
          /* do something */
}
p = func;

p的赋值可以不同,但一定要是函数的地址,并且署名和返回类型相同。

如何传递回调函数的地址给调用者?现在可以将p传递给另一个函数(调用者)如caller(),它将调用p指向的函数,而此函数名是未知的:

void caller(void(*ptr)())
{
          ptr(); /* 调用ptr指向的函数 */
}

void func();

int main()
{
          p = func; 
          caller(p); /* 传递函数地址到调用者 */
}

如果赋了不同的值给p(不同函数地址),那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。

函数指针在linux中的应用:以signal函数为例。在Unix/Linux中signal函数是比较复杂的一个,其定义原型如下:

void (*signal(int signo,void (*func)(int))) (int)

分析如下:

signal(int signo, void(*func)(int))是signal函数的主体,需要两个参数:int型的signo,以及一个指向函数的指针。

void (*func)(int)这个函数中,最外层的函数体void (* XXX )(int)表明其返回值是一个指针(函数指针),指向一个函数XXX的指针,XXX所代表的函数需要一个int型的参数,返回void。

由于其复杂性,可用typedef来对其进行简化

typedef void sigfunc(int);//这里可以看成一个返回值 .

再对signal函数进行简化就是这样的了

sigfunc *signal(int, sigfunc *);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值