今天与几个同窗看到了一个函数指针定义:安全
void (*f(int, void (*)(int)))(int)函数
之前在C trap pit fails里面见过,可是文章里面介绍的很详细,可是每每使初学者抓不到重点, 结果弄的一头污水。这里就简单介绍一下这中函数指针的定义方法。spa
这个问题从定义的角度来看很好理解,指向函数的指针就是函数指针,可是咱们如何声明一个函数指针呢?又如何将一个地址强制转换为某一个类型的函数指针呢?这里看下面一个例子源码:指针
void function(int a)源码
{it
a = 5;io
}function
void (*pfunc)(int); 变量
很简单,上面这段代码声明了一个函数fucntion和一个函数指针pfunc, 它指向的函数就是一个具备void返回值,int参数的函数。若是将function函数的地址给pfunc指针,能够简单的经过下面两种赋值:语法
pfunc = function;
或者
pfunc = &function;
经过指针调用该函数,也有两种方法:
pfunc(5); 或 (*pfunc)(5);
咱们看一下赋值语句,pfunc = function; 但有时候多是一个常数0x8999940, 它刚好也表示一个安全的与function相同的函数,如何将这个数值赋给pfunc呢?显然咱们须要强制类型转换,应该将该常数转换成什么类型呢?这就是问题的关键!
在void (*pfunc)(int)语句里面,只有pfunc是变量名称,那么剩余的部分,void(*)(int),就是咱们须要的转换类型。所以,新的赋值语句是:
pfunc = (void (*)(int)) 0x8999940;
赋值完成后,就能够经过pfunc(5); 或 (*pfunc)(5);调用相应的函数了。
若是理解了上面的内容,咱们就能够解释void (*signal(int, void (*)(int)))(int)这个相对复杂的问题了
如今咱们先抛开上面那个复杂的定义,先看一下下面的需求1) 定义一个函数;2) 该函数具备如下特色,两个参数,返回值是函数指针,而且一个参数也是函数指针。假如返回值和参数函数指针同为void (*)(int); 另外一个函数参数是int型。该函数定义名称为my_func。
根据需求咱们能够很容易定义出这种函数:
typedef void (*HANDLER)(int); // 参数函数和返回函数定义
HANDLER my_func(int, HANDLER);
忽然需求中又不让使用typedef,这就是早期C语言不支持typedef的状况,那么如何定义这种函数呢?
咱们假如说my_func的返回值是int,是否是它的定义能够这么写:
int my_func(int, void (*)(int));
也就是说,my_func(int, void (*)(int))就是一个int型数据。如今将int换成一个函数,也就是
void (*)(int) my_func)(int, void (*)(int);
这样一种定义,显然这种语法不支持,那么,实际是如何表示呢?回过头来,咱们先看看函数指针的声明格式
void (*pfunc)(int);
其中pfunc 等价于 void (*)(int)。如今在看看上面的格式,是否是很相识,对了,pfunc就是my_func(int, void (*)(int))。如今若是将二者代替一下是否是就成了这种格式:
void (*my_func(int, void(*)(int)))(int)
若是将my_func换成signal,是否是就是咱们文章开始提到的那个复杂声名?如今是否是明白了,原来如此啊,它是一个返回函数指针的的函数声名!