现在的位置: 首页 > 综合 > 正文

void (*f(int, void (*)(int)))(int) 函数解析

2017年10月12日 ⁄ 综合 ⁄ 共 1682字 ⁄ 字号 评论关闭


函数指针

 原文链接:http://blog.csdn.net/baishuwei/article/details/3210810

今天与几个同学看到了一个函数指针定义:

 

void (*f(int, void (*)(int)))(int)

 

以前在C trap pit fails里面见过,但是文章里面介绍的很详细,但是往往使初学者抓不到重点,
结果弄的一头污水。这里就简单介绍一下这中函数指针的定义方法。

 

什么是函数指针?

 

这个问题从定义的角度来看很好理解,指向函数的指针就是函数指针,但是我们如何声明一个函数指针呢?又如何将一个地址强制转换为某一个类型的函数指针呢?这里看下面一个例子源码:

void function(int a)

{

      
a = 5;

}

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,是不是就是我们文章开始提到的那个复杂声名?现在是不是明白了,原来如此啊,它是一个返回函数指针的的函数声名!

抱歉!评论已关闭.