在阅读Liunx/UNIX系统编程手册一书在阅读到第20章时遇到函数signal()的声明时完全不懂这个函数是什么意思,于是网上搜索,有几个帖子里面介绍的方法是《C专家编程》一书第三章中相关内容,本文就是为了弄懂函数signal()的声明。
在阅读了本章内容后,我尝试用自己的语言来解释函数signal()的声明,如果有幸有朋友看到,希望可以批评指正。
首先介绍signal()函数声明前先了解函数指针,参考C函数指针基础.
首先函数signal()的原型:

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

分析如下形式:

void(*signal(                                             ))(int)
signal是一个函数,它的返回值是一个函数指针,而它的参数中有一个函数指针形式void (*handler)(int)
借助于typedef来进行简化如下:
/*定义函数指针返回值是void,参数是int型*/
typedef void (*ptr_to_func)(int)
/*表明signal是一个函数,接受两个参数,其中一个是函数指针,返回值也是函数指针*/
ptr_to_func signal(int ,ptr_to_func);

Linux/UNIX系统编程手册中的例子:

#include <signal.h>
#include "tlpi_hdr.h"

static void
sigHandler(int sig)
{
    printf("Ouch!\n");                  /* UNSAFE (see Section 21.1.2) */
}

int
main(int argc, char *argv[])
{
    int j;
    if (signal(SIGINT, sigHandler) == SIG_ERR)
        errExit("signal");
    for (j = 0; ; j++) {
        printf("%d\n", j);
        sleep(3);                       /* Loop slowly... */
    }
}

stackoverflow上的解释:

附常见声明形式解析:
No 1.

int (*func_p)(double)

解读:
func_p首先是一个函数指针.
func_p是一个指向参数为double,返回值为int的函数指针.

No 2.

int *hoge[10]

hoge是一个指向int的指针的数组(元素个数为10)

No 3.

double (*array_p)[3]

array_p是指向double(元素个数为三)的数组的指针
array_p = &array;这样赋值没有问题,因为类型相同。
如果array_p=array编译器就会发出警告,提示如下:
指向int的指针和指向int的数组(元素个数3)的指针是完全不同的数据类型.

No 4.

int *func_table[10])(int a)

指向返回int的函数(参数类型是int)的指针的数组(元素个数为10)
范例:

/*
    Name: 函数指针数组
    Copyright: 52coder.net
    Author: 52coder
    Date: 03/06/17 17:24
    Description: pointer
 */

#include <stdio.h>
#include <stdlib.h>

int func(int a)
{
    printf("function func\n");
    return a;
}

int main()
{
    int (*func_table[10])(int a);
    func_table[0]=func;
    func_table[0](2017);
    
    func_table[1]=func;
    func_table[1](2018);
    return 0;
}

No 5.
C语言中不存在多维数组.
对于如下声明:

int hoge[2][3];
解读为:数组hoge有2个元素,元素类型是int[3的数组]

No.6
左值与右值的区别
表达式代表某处的内存区域的时候,我们称当前的表达式为左值,相对的是表达式只是代表值的时候,我们称当前的表达式为右值.