函数指针

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

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

void (*f(int, void (*)(int)))(int) 函数解析的更多相关文章

  1. void (*f(int, void (*)(int)))(int) 函数解析 转

    今天与几个同学看到了一个函数指针定义: void (*f(int, void (*)(int)))(int) 以前在C trap pit fails里面见过,但是文章里面介绍的很详细,但是往往使初学者 ...

  2. void f(int(&p)[3]){} 和void f(int(*p)[3]){}的差别

    #include<iostream> using namespace std; void f(int(&p)[3]){          cout<<p[0]<& ...

  3. signal函数:void (*signal(int,void(*)(int)))(int);

    http://blog.chinaunix.net/uid-20178794-id-1972862.html signal函数:void (*signal(int,void(*)(int)))(int ...

  4. (转+原)VC编译错误:uafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已经在 LIBCMT.lib(new.obj) 中定义

    参考网址:http://zhanyonhu.blog.163.com/blog/static/16186044201023094754832/ 1>uafxcw.lib(afxmem.obj) ...

  5. “void * __cdecl operator new(unsigned int)”(??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

    转自VC错误:http://www.vcerror.com/?p=1377 问题描述: 当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序有误时,可能会出现以下 L ...

  6. Solve Error: nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in libcpmt.lib(newaop.obj)

    Error: nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)&quo ...

  7. uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)"解决办法

    如果在编译MFC程序的时候出现下列及类似的错误: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator ...

  8. MFC程序出现uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)解决办法

    在同一个地方摔倒两次之后,决定记录下来这个东西. 问题 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl opera ...

  9. STL函数static void (* set_malloc_handler(void (*f)()))()与函数指针解析

    在C++ STL的SGI实现版本中,一级空间配置器class __malloc_alloc_template中有一个静态函数的实现如下: static void (*set_malloc_handle ...

随机推荐

  1. 卓越网的kindle paperwhite

    卓越网的kindle paperwhite, 899元的价钱,好吸引啊,我是不是也应该买一个呢,从卓越网中看见kindle paperwhite的1代开始,一直想买,等到现在的2代也出了,也继续在考虑 ...

  2. target vs currentTarget, clientWidth vs offsetWidth

    width: document < window(browser) < screen document--> clientWidth < offsetWidth(include ...

  3. Gridview中的数据导出到excel中

    protected void btnExport_Click(object sender, EventArgs e)    {                   //导出全部数据,取消分页      ...

  4. 更改Altium中PCB大小/精确确定板子尺寸

    使用原理图生成PCB后,Altium Designer会根据原理图大小自动生成一块黑色区域,还有一个在禁止布线层的方框,还有两段标注板子大小的线.下面说一下如何更改黑色区域的大小,还有如何精确确定板子 ...

  5. VS2008 运行VC\Bin下的link.exe, cl.exe, lib.exe提示找不到mspdb80.dll的解决方法

    天在用link.EXE的LIB命令生成用于连接(LINK)使用的lib文件时提示:找不到mspdb80.dll. 原因:Microsoft Visual Studio\VC\Bin\下没有 “msob ...

  6. javascript 误用this指针 的情况

    理解了this指针后,我们再来看看一些很容易误用this指针的情况. 示例1——内联式绑定Dom元素的事件处理函数 <script type="text/javascript" ...

  7. 2015第24周五Spring的AOP

    AOP(面向方面编程:Aspect Oriented Programing)和IoC一样是Spring容器的内核,声明式事务的功能在此基础上开花结果.但AOP的应用场合是受限的,它一般只适合于那些具有 ...

  8. Numerical Methods with MATLAB(1)

    目前正在阅读MATLAB相关的书籍:Numerical Methods with MATLAB,现在感觉这本书写的还行, 细致基础,而且写的比较清楚,同时把malab和数值算法结合在一起. 目前刚看完 ...

  9. RMI入门教程

    一.什么是RMI Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运 ...

  10. Eclipse设置保存时自动给变量加final

    也是针对checkstyle的,在代码检查规范时,所有的变量必须是final.为了解决这个问题,通过以下的设置可以在eclipse保存时,自动给没有加final的变量加上final. Window-& ...