最近在学习unix编程,看了看别人写的小游戏代码,于是学习了signal()函数。
signal(SIGWINCH, (void (*)(int)) handle_signal);
上面这一行是小游戏的源代码
第一个参数是指信号类型,一般都是int类型的宏定义常量
SIGWINCH 表示的是当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程。还有许多这样的宏定义,都是以SIG开头,如SIGABORT, SIGALRM, SIGFPE等等....这里我就不一一例举了,自行google。
第二个参数 用到了函数指针这个概念。
函数指针:
其实就是用一个指针指向函数的地址,等于说第二个参数就可以直接跳转到那个函数,从而在函数参数中直接执行另外一个函数。
函数指针的声明方法为:
以下是一个最简单的例子,这里可以看出,函数指针和其他变量指针的声明和指向是类似的。
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
不过注意,指向函数的指针变量没有++和--运算,用时要小心。
现在我们看一下signal()函数的原型
上面是一个signal()函数的声明,其中有两个参数 int signum 和 函数指针handler 该函数指针可指向一个 void fuction( int ) 类型的函数,。
函数signal() 的返回值是一个 函数指针, 函数指针指向 void fuction( int ) 类型的函数
另外signal()函数原型还可以用这种方法表示
类似这种用法
所以继续切入正题,看函数的第二个实参数,因为handler 函数的原型是void 而 行参是 void ( * handler) (int ), 所以前面要加(void (*)(int)) ,就是把void 强转成 带有一个参数int 返回为void 的函数指针。
不过注意,指向函数的指针变量没有++和--运算,用时要小心。
现在我们看一下signal()函数的原型
void ( *signal(int signum, void(* handler)(int)) ) (int);
这个原型又让人迷惑了。。。。下面我们来解释一下这个原型
上面是一个signal()函数的声明,其中有两个参数 int signum 和 函数指针handler 该函数指针可指向一个 void fuction( int ) 类型的函数,。
函数signal() 的返回值是一个 函数指针, 函数指针指向 void fuction( int ) 类型的函数
另外signal()函数原型还可以用这种方法表示
typedef void(* sig_t) ( int );
sig_t signal(int signum, sig_t handler );
这是利用typedef 隐藏了函数指针原型
类似这种用法
typedef char T[81];
T ch;
则T这个变量类型就表示声明80个字符的数组
所以继续切入正题,看函数的第二个实参数,因为handler 函数的原型是void 而 行参是 void ( * handler) (int ), 所以前面要加(void (*)(int)) ,就是把void 强转成 带有一个参数int 返回为void 的函数指针。