问题提出

请分析此声明:void (*signal(int sig, void (*handler)(int)))(int);

求解过程

在对上面的例子作分析之前,我们需要了解C语言的声明优先级,《C专家编程》P64原文如下:

规则A规定了要按照优先级来解释声明(算是一句废话)。规则C请参照本人上一篇笔记:http://www.cnblogs.com/deyuanqin/p/5705967.html。规则B的具体实践过程如下图:

本着抛砖引玉的目的,我们使用以上规则分析void (*signal(int sig, void (*handler)(int)))(int)这个复杂的声明。从易到难的顺序:

1. void (*handler)(int):

handler右边是圆括号,所以handler不是数组或者函数。再看其左边,是*(星号),所以handler是一个指向****的指针

(*handler)(int)。(*handler)的右边是圆括号,因而(*handler)(int)中的()(int)是一个返回****的函数。结合上一步分析,handler是一个指向返回****的函数的指针。

③ (*handler)(int)的右边没有符号,左边是void。综上,handler是一个指向返回void值的函数的指针

2. void (*signal(int sig, void (*handler)(int)))(int):

void (*handler)(int)在上面的步骤已经做了分析,我们可以使用语句typedef void (*handler)(int)将其简化(将handler声明为一个新的类型,这个类型是是一个指向返回void值的函数的指针。有关typedef的知识改日再做分析),则void (*signal(int sig, void (*handler)(int)))(int)就被简化为void (*signal(int sig, handle h))(int)。下面我们对void (*signal(int sig, handle h))(int)作分析:

signal右边是圆括号,因而signal()是一个返回****的函数

signal()的左边是*,因而signal()是一个返回指向****的指针的函数

 (*signal(int sig, handle h))右边是圆括号,因此(*signal(int sig, handle h))(int)是一个返回****的函数。综上,signal是一个返回指向返回****函数的指针的函数

④ (*signal(int sig, handle h))右边是void。因而,signal(这个标识符)是一个返回指向返回void值的函数的指针的函数

以上的分析过程可能有错漏,请各位看官多指教。

参考资料

1.《C专家编程》P65图3-1

2.博客http://blog.csdn.net/jiuyueguang/article/details/9350903

C语言复杂声明-void (*signal(int sig, void (*handler)(int)))(int);的更多相关文章

  1. void (*signal(int sig, void (*func) (int))) (int)理解

    http://blog.csdn.net/sever2012/article/details/8281271 1.signal( int sig, void (*func)(int))signal是一 ...

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

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

  3. 《C专家编程》第三章——分析C语言的声明

    前面一章我们已经说过C语言存在的一些问题和它晦涩的地方,让我们对这门神奇的语言有了更深的了解.现在这一章则集中精力来讨论C语言的声明,分为三块,首先是说明C语言声明晦涩难懂的原因和声明是如何形成的,其 ...

  4. 浅谈C语言变量声明的解析

    C语言本身提供了一种不甚明确的变量声明方式——基于使用的声明,如int *a,本质上是声明了*a的类型为int,所以得到了a的类型为指向int的指针.对于简单类型,这样声明并不会对代码产生多大的阅读障 ...

  5. signal函数的原型声明void (*signal(int signo, void (*fun(int))))(int)分析

    转:http://blog.sina.com.cn/s/blog_4850a7880100hnam.html void (*signal(int signo, void (*fun(int))))(i ...

  6. 如何理解这段代码:void (*signal (int sinno,void(*func)(int)))(int)

    void (*signal (int sinno,void(*func)(int)))(int) 先来看void(*func)(int)   这里的意思是声明一个函数指针func,它的参数类型为int ...

  7. signal函数理解或者void (*signal(int signum,void(*handler)(int)))(int)理解

    把void (*signal(int signum,void(*handler)(int)))(int)分成两部分: typedef void (*sighandler_t)(int); sighan ...

  8. 简单理解函数声明(以signal函数为例)

    这两天遇到一些声明比较复杂的函数,比如signal函数,那我们先简单说说signal函数的用法:(参考<c陷阱与缺陷>) [signal:几乎所有c语言程序的实现过程中都要用到signal ...

  9. C语言复杂声明

    C语言复杂声明 First step int *f(); /* f:是一个函数,它返回一个指向int类型的指针*/ int (*pf)(); /* pf:是一个指向函数的指针,该函数返回一个int类型 ...

随机推荐

  1. hibernate5ID生成策略

    1.uuid2:使用JDK自带的UUID生成36位的ID 2.guid: 3.uuid:生成32位的uuid,不符合ETF RFC 4122标准,已被uuid2取代. 4.uuid.hex:等同uui ...

  2. java IO之AutoCloseable,Closeable和Flushable接口

    有3个接口对于流类相当重要.其中两个接口是Closeable和Flushable,它们是在java.io包中定义的,并且是由JDK5添加的.第3个接口是AutoColseable,它是由JDK7添加的 ...

  3. [css3]叉叉旋转效果

    .close_frame{display:inline-block;height:14px;width:14px;background:url("../images/closeiframe. ...

  4. Git 配置

    在 windows 上安装完 Git 会右键菜单中看到 Git 的快捷打开选项, 点 Git Bash Here 就可以在当前目录下打开 Git 的命令行 Git shell,初次使用 Git 先配置 ...

  5. app上传到App Store的快捷方法及步骤

    跳过证书的申请及配置概要文件的设置, 现在根据已有的配置概要文件及发布证书开始: 1.先在Xcode上的PROJECT和TARGETS->Build Setting->Code Signi ...

  6. JS中函数的调用和this的值

    调用每一个函数会暂停当前函数的执行,传递控制权和参数给新函数.除了声明时定义的形式参数,每个函数还接收两个附加的参数:this 和 arguments. 参数this在面向对象编程中非常重要,他的值取 ...

  7. 如何隐藏DOM元素

    在CSS中,要隐藏DOM元素常见的方法有: 设置元素的opacity值为0 设置元素的visibility值为hidden 设置元素的display值为none 设置元素的position值为abso ...

  8. 修改Oracle监听端口

    修改oracle监听端口 修改端口号的整体步骤:1.1   查看当前监听的状态1.2   停止监听1.3   修改监听文件的端口号1.4   修改初始化参数local_listener1.5   重启 ...

  9. Ionic的跨域问题

    跨域大家都不陌生,但最近一直遇到一个坑,也是自身对ajax和angular的不深入造成,所以记录一笔,下次遇到绕过. 参考过:http://ionichina.com/topic/54f051698c ...

  10. 开发中的一些解决方案(c#)

    1.如果需要配置文件,不妨考虑用XML序列化技术实现XML配置文件.在C#中引入System.Xml.Serialization命名空间,编写实体类序列化到XML文件中(或反序列化到对象),编写少量代 ...