http://blog.chinaunix.net/uid-20178794-id-1972862.html

signal函数:void (*signal(int,void(*)(int)))(int); 
2008-04-11 15:26:02

signal函数:void (*signal(int,void(*)(int)))(int)

#include <signal.h>
void (*signal (int sig, void (*func)(int)))(int);

That is to say, signal is a function that returns a pointer to another function. This second function takes a single int argument and returns void. The second argument to signal is similarly a pointer to a function returning void which takes an int argument.

这个例子来自《C陷阱与缺陷》……

signal函数是著名的信号函数,但是它的定义却非常的复杂……

任何C变量,都是由“类型”+“表达式”组成,它表示,对“表达式”求值,返回的类型,是声明给定的“类型”的值,如

 

CODE:

int a;

也就是对表达式a求值,是一个int类型;

同样地,

 

CODE:

int func();

这个声明的含义是,对表达式func()求值结果是一个int类型,也就是说,func是一个返回值是int类型的函数。

进一步,

 

CODE:

int *a;

也就是,*a是一个整型变量,那a当然就是一个指针,一个指向整型类型变量的指针;

那么,

 

CODE:

int *func();

同样地,因为()的优先级高于*,所以func是一个函数,它返回一个整型变量指向整型变量的指针;

进一步地,

 

CODE:

int (*func)();

这一回*被括号括了起来,因为*被先执行,所以,func自然地是一个指针,它指向的类型是一个函数
,即func是一个指向函数的指针,
并且,这个函数,返回一个整型变量。

另一个要讨论的问题是,如何得到一个类型指定的类型转换符,比如:
int a;
float b;
要强b转换为int类型,需要把
int a;
中的变量名去掉,然后把末尾的;去掉,再把剩余的部份用括号括起来,即:
(int)
所以,以下表达式:
int (*func)();
如果我们要得到对应的函数指针的类型转换符,则把func去掉,再把;去掉,再用括号
把剩余的部份括起来,即:

 

CODE:

(int (*)())

表示一个“指向返回值为整型类型的函数的指针”的类型转换符。

那么,如果要将常数0,转换为一个函数指针,且这个函数返回值类型为void类型,应该如何表示呢?
根据上面所说,
(void (*)())
这个也就不用再解释,那么,要强制类型转换也很简单:
(void (*)())0
现在,它已经是一个函数指针了,把它简写为fp:
#define fp (void (*)())0
要调用这个函数指针,很简单,
(*fp)()
当然,fp是一个函数指针,这样的调用形式,可以简写为
fp()
,当然,这仅仅是简写……
所以,(*fp)(),把fp这个宏展开:
就是

 

CODE:

(*(void (*)())0)()

这么复杂的东东,其实很简单,就是先为常数0进行类型转换,转换为一个“指向返回类型为void的函数指针”,然后
再调用它。

用typedef来简化(*(void (*)())0)():

 

CODE:

typedef void (*funcptr)();
(*(funcptr)0)();

著名的signal函数的声明,就是这样啦:

 

CODE:

void (*signal(int,void(*)(int))(int);

同样地,用typedef可以简化它:

 

CODE:

typedef void (*HANDLER)(int);
HANDLER signal(int,HANDLER);

这已经是我们习惯看到的形式了。

signal函数:void (*signal(int,void(*)(int)))(int);的更多相关文章

  1. 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 ...

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

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

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

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

  4. 信号之signal函数

    UNIX系统的信号机制最简单的接口是signal函数.signal函数的功能:为指定的信号安装一个新的信号处理函数. #include <signal.h> void (*signal(i ...

  5. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

  6. POSIX信号和自定义signal函数

    一.信号的概念 信号(signal)就是告知某个进程发生了某个事件的通知:信号通常是异步发生的,也就是说接受信号的进程不知道信号的准确 发生时刻:信号可以(1)由一个进程发给另一个进程:(2)由内核发 ...

  7. 三十、Linux 进程与信号——信号的概念及 signal 函数

    30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...

  8. 【VS开发】程序如何捕捉signal函数参数中指定的信号

    当说到signal的功能时,我们都知道它会捕捉我们所指定的信号,然后调用我们所指定的信号处理函数.但它是如何捕捉我们指定的信号的呢?下面我就以msdn上关于signal的example为例,说明sig ...

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

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

随机推荐

  1. PAT 1087【二级最短路】

    二级最短路+二级最短路,就是DP过程吧. 代码稍微注释一些,毕竟贴代码不好.. #include<bits/stdc++.h> using namespace std; typedef l ...

  2. springMVC容器加载源码分析

    springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下spring ...

  3. Gson本地和服务器环境不同遇到的Date转换问题 Failed to parse date []: Invalid time zone indicator

    GoogleGson在处理Date格式时有个小陷阱,在不同环境中部署时可能会遇到问题. Gson默认处理Date对象的序列化/反序列化是通过一个SimpleDateFormat对象来实现的,通过下面的 ...

  4. 小程序外部向组件内部传递externalClasses -- 传入样式wxss

    1.组件的JS添加配置 // 外部传入class类 externalClasses:['my-class'], 2.组件的wxml写法: 3.调用的页面 4.调用页面的wxss: 由于小程序的限制必须 ...

  5. linux下ssh key秘钥登陆远程服务器设置

    本地的用户名需要和ssh服务器的用户名一致 1.在Server服务器上加载私钥文件ssh-add wang_rsa 2.如果系统提示:could not open a connection to yo ...

  6. Caused by: MetaException(message:Hive Schema version 2.1.0 does not match metastore's schema version 1.2.0 Metastore is not upgraded or corrupt)

    解决方案汇总: ()删除HDFS上的hive数据与hive数据库 hadoop fs -rm -r -f /tmp/hive hadoop fs -rm -r -f /user/hive ()删除My ...

  7. 031 Next Permutation 下一个排列

    实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列.如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列).修改必须是原地的,不开辟额外的内存空间.这是一些例子,输入 ...

  8. ST的MCU系列

    一 STM32F1(M3)系列: 超值型系列STM32F100-  24 MHz最高主频 带马达控制和CEC功能 基本型系列STM32F101 - 36 MHz最高主频,具有高达1M字节的片上闪存 U ...

  9. Java集合——集合框架Iterator接口

    1.集合输出 很多情况下我们需要把集合的内容进行输出,也就是遍历集合. 遍历集合的方式有以下几种: 1.Iterator 2.ListIterator 3.Enumeration(枚举方式,比较老一般 ...

  10. js统计字符出现次数

    var s = "The rain in Spain falls rain mainly in the rain plain"; var reg = new RegExp(&quo ...