类似void(*signal(int, void(*)(int)))()的说明, 经典或者不经典的书籍, 都有过解读, 《C专家编程中》, 设定了一套长长的解读规则, 记住它恐怕绝非易事, 后面终于在《C traps and pitfalls》找到能让人轻松的解释。 下面个人对这方面的理解。 建议大家翻阅一下 书的2.1节
a. 类型
b. 表达式性质的声明符号
看例子:
函数显然是满足上面的要求
float ff(); ff()是一个声明符号, 同样, 是一个表达式(解读为:ff是一个float类型的表达式, 并且是一个函数, ff是一个返回值类型为float的函数).
变量的例子: float f, *g; 可以写成: float (f), ((*g)), 所以加括号后, 不难发现, 这是一个表达式(f是一个float类型的表达式, 并且是一个变量, 结论为f是一个float类型的变量; g是一个float类型的表达式, 并且是一个指针变量,结论为g为float类型的指针变量)
因此, 函数声明和变量声明没有区别:
函数声明的结果, 就是声明了一个具有某种类型的“变量”. 该“变量”的类型为函数返回类型, 名称为函数的名称。
广义上,对函数的理解,实质就是一个变量,这个变量,即函数的返回值。
举两个简单例子:
float *g(), (*h)();
由于括号的优先级结合规律高于*, 所以原式可以写为:
float *(g()), ((*h))()
结合理解一和理解二, 对第一个声明:
让ggg代替g(), 表达式变为: float *(ggg); 说明整个表达式是一个float类型的指针, 这个表达式的名称为ggg.
由于ggg == g(), 这是一个函数, 所以整个表达式为: g是一个返回float指针类型的表达式, 并且为函数。===》g为一个返回float指针类型的函数。
对于第二个声明:
让hhh代替*h, 表达式变为: float hhh(): 说明整个表达式是一个float类型的表达式, 并且名称为一个函数.
由于hhh == *h , 既然hhh为一个函数表达式, 则h必定是函数指针。==》h是一个函数指针. 返回值为float类型
上述例子中, float (*h)(); 粗旷的类型定义为浮点表达式(float s, s==(*h)()), 细节的类型定义为参数为void函数, 返回为float(float s(), s = *h ); 再细节的定义为函数指针float (*h)();
这些定义完全是从理解的角度来划分层次的。 这种划分是要看对定义理解的帮助。
下边的例子, 划分的层次需要粗旷, 原因是较复杂。
void(*signal(int, void(*)(int)))(int)
粗旷划分:
void (*fff)(int) 表达式返回为函数指针
表达式为一个函数: signal(int, void(*)(int))
这个层次上的理解是对我们最有帮助的, 解释为: 表达式返回了一个函数指针, 这个表达是为一个函数表达式。
当然如果你要这样理解:
void (fff)(int) 表达式返回为函数指针
表达式为一个函数: *signal(int, void(*)(int))
完全是个人喜好, 进一步划分, 可以按照嵌套递归原则, 将其剥落出来.