C语言难点专题——复杂的函数声明

类似void(*signal(int, void(*)(int)))()的说明, 经典或者不经典的书籍, 都有过解读, 《C专家编程中》, 设定了一套长长的解读规则, 记住它恐怕绝非易事, 后面终于在《C traps and pitfalls》找到能让人轻松的解释。 下面个人对这方面的理解。 建议大家翻阅一下 书的2.1节

 

1. 理解之一. 无论是变量声明, 还是函数声明, 包含两方面的内容

     a.    类型

     b.    表达式性质的声明符号

看例子:

函数显然是满足上面的要求

float ff();                ff()是一个声明符号, 同样, 是一个表达式(解读为:ff是一个float类型的表达式, 并且是一个函数, ff是一个返回值类型为float的函数).

变量的例子:   float f, *g;                可以写成: float (f), ((*g)), 所以加括号后, 不难发现, 这是一个表达式(f是一个float类型的表达式, 并且是一个变量, 结论为f是一个float类型的变量; g是一个float类型的表达式, 并且是一个指针变量,结论为g为float类型的指针变量)

 

 

 

因此, 函数声明和变量声明没有区别:

函数声明的结果, 就是声明了一个具有某种类型的“变量”. 该“变量”的类型为函数返回类型, 名称为函数的名称。

广义上,对函数的理解,实质就是一个变量,这个变量,即函数的返回值。

 

 

 

 

2. 理解之二, 无论是变量还是函数, 弄清楚外围返回值(也就是类型), 再层层剖析, 问题迎刃而解

举两个简单例子:

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类型

 

3. 适度拿捏解析的程度, 方便理解.


上述例子中, 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)) 

 

完全是个人喜好, 进一步划分, 可以按照嵌套递归原则, 将其剥落出来.

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值