做Linux下软件开发的对signal函数应该不会陌生,但是你看过它的函数原型吗?如果你看了,你懂它了吗。要是有疑问,来看看我的解释吧。
先说说signal函数是干嘛的。
signal函数用于向系统注册处理某一信号的函数,说白了,就是告诉系统,当某个信号发生了,执行这个函数。
当signal被调用时,它返回调用前处理同意信号的函数的指针。
在signal.h头文件中,它的声明如下:
void (*signal (int sig_num, void (*handler)(int))) (int)
第一次看到这么一个东西,我一下子懵了,我真不知道,还有这样的函数定义。
现在就让我们一起,一步一步、一层一层地剥掉它的小括号。
前面说到,signal函数返回值是函数指针(如果不太清楚函数指针,可以先到文章的后半部分看看,也可以看看我的另一篇关于函数指针的文章),这个指针指向的函数的签名如下:
void (*fp) (int) //pointer to a function
函数签名本不包含返回值类型的,但是函数指针记录了此信息。
对应到上面的函数原型,这里的 fp 相当于
signal (int sig_num, void (*handler)(int))
到这里,我们找出了函数的返回值类型,上面的这段看上去就亲切得多了,这就是我们平时所说的函数签名了。
函数名signal,参数列表包括一个整型值和一个函数指针。又是一个函数指针,你发现了吗,这个函数指针:
void (*handler)(int)
和上面的那个函数指针其实是一样的,其实这不难理解,因为signal函数的返回值就是信号处理函数的地址。
好了,现在的signal看着没那么可怕了。接着用吧……
关于函数指针
函数指针是一类特殊的指针,它存储的是函数的入口地址,也就是说,通过这个指针,你可以调用函数。
函数指针对其可以指向的函数的签名和返回值类型有严格的要求,否则,无法将某个函数地址赋给一个函数指针,举个例子。
//定义一个可以指向返回值为void,参数为两个int型的函数指针, //注意这里的*和()的位置,很重要 void (*fp)(int, int)
如果某个函数的原型是void function(int a, int b),则可以进行如下赋值和调用:
fp = function; //函数名不接括号和参数即表示此函数的地址 function (5,6); fp(5,6); //这与上面的function(5,6)调用具有同样的效果
还有一个很大的不同,普通的指针可以进行强制类型转换,但是函数指针不可以。
说了这么多,到底函数指针有什么用途呢,我想典型的用处是动态调用具有相同签名和返回值的不同函数,即在不同的条件下,调用不同的函数。
(待续……稍后会附上一个简单的例子)
结束……希望对大家有用