c变量的声明有两部分组成:类型和声明符,对声明符求值得到结果类型为给定的类型。
举个最简单的例子
int a;
a的类型就是上述声明中指定的类型,即int型。
同样,在来看指针和函数的声明,这里不考虑指针的初始化问题。
int * p;
int foo1(void);
int *foo2(void);
int (*foo3)(void);
*p求值结果的类型为int型,因此p的类型就是指向int型变量的指针。
foo1(void)求值结果为一个int型数,那么foo1就是返回值为int型数的函数,无参数。
注意第三个声明,()的优先级高于*,因此*foo2(void)可以看作*(foo2(void)),对其求值结果为一个int型数,那么foo2(void)结果就是指向int型数的指针,因此foo2是返回值为指向int型数指针的函数。
第四个声明中,(*foo3)(void)求值结果是int数,因此(*foo3)为返回值为int数的函数,最终得出foo3是指向这个函数的指针,即foo3指向返回值为int型数的函数。
上面就是基本的类型声明,不论多复杂的函数声明都是用上述的声明方式组合而来的。在分析题中的函数声明之前,再说明一下类型转换符,c中需要强制转化一个数据类型时,在数据前加上(类型关键字),比如
int a;
a = (int)(1.0);
简单类型可以这样,那么复杂类型怎么做强制转化呢?其实很简单,将之前定义类型声明语句的变量名和;去掉,再将剩余的部分还是放在一个括号中就可以了,其实也适用于简单类型。
int (*foo4)(void);
上面的声明定义了指向返回值为int型数的函数的指针,那么该类型的类型转换符为(int (*)(void))。
最后回到题中的函数声明。
先来分析signal函数的参数,一个为代表信号的int型数,一个指向信号处理函数的指针,那返回值呢?返回值就是指向信号处理函数的指针。
再来看看信号处理函数定义,参数为代表信号的int型数,无返回值。
void sigfunc(int n)
{
/*
信号处理代码
*/
}
那么现在可以得到这个自定义的信号处理函数声明
void sigfunc(int);
怎么得到一个指向自定义的信号处理函数的指针呢?很简单,假设该指针名为pfunc,则*pfunc就代表了sigfunc函数,因此指向自定义信号处理函数的指针声明为
void (*pfunc)(int);
signal函数的返回值类型与pfunc类型相同,即pfunc可由signal(arg1,arg2)代替,其中arg1和arg2分别为代表信号的的int型数和指向自定义信号处理函数的指针。
void (*signal(int n,void (*pfunc)(int)))(int)
将其中的变量名省略就是signal函数的声明
void (*signal(int,void (*)(int)))(int)
以上都是我自己参考中第2章而写,之前自己看过一边,在这个问题上一直没有较深理解,这次回答也相当于自己再思考一遍这个问题,希望大家指点。