C经典书籍笔记——c陷阱与缺陷②(语法陷阱之函数声明)

目录

一、前言

 二、理解函数声明

1.问题思考

2.什么是声明

3.分析  (*(void(*)())0)()


一、前言

 

C经典书籍笔记——c陷阱与缺陷②(语法陷阱之函数声明)


 二、理解函数声明

1.问题思考

(*(void(*)())0)();

 如果你还不能轻松解决,请看下面的细细分解( • ̀ω•́ )✧

构造这种表达式的基本规则:按照使用的方式来声明

2.什么是声明

声明类型声明符组成

①、简单的一个声明

float f,g;

类型:float 

声明符:f,g(最简单的声明符就是单个变量)

声明:当对其求值的时候,表达式f,g的类型为浮点数类型

(我们可以在声明符中任意添加“()”,如   float  ((f));)

②、声明可以组合

float pa();
float *pb;
float *pa(),(*pb)();

第三行的式子可以看成一二两行的不同组合。在组合时要注意优先级的问题,如这里的()优先级高于*。

③、类型转换符

知道了声明变量的规则,我们就可以轻松得到该变量的类型转化符

基本方法:只需把变量名和末尾的分号去掉即可

3.分析  (*(void(*)())0)()

 

我们不妨从该函数得功能出发,探讨对该函数的理解。现在开始我们的反向推演

功能调用储存位置为0的函数

1.我们首先需要一个函数指针,根据声明的使用我们需要声明符和类型:

void(*fp)()

 声明符fp,类型void(*)()

2.调用函数

(*fp)() 

[注意:函数指针在定义是(*fp)外面的()不可省略,因为优先级的问题。在调用函数时则可以写为fp() ]

3.我们需要一个地址为0的指针代替fp

你可能会这样调用(*0)(),但遗憾的是*只能解引用指针类型变量

4.因此我们需要强制类型转化

我们需要将0的类型转化为函数指针,这样才能调用函数,朝着这个方向,我们写下:

(void(*)()) 0

得到地址为0的函数指针后我们对其调用(* (  void(*)() 0 ) ) ()

5.利用typedef的简化

typedef void(*func)();
(*(func)0);

[注意:函数指针类型的变量在声明时,变量名紧跟*后   。void(*)()func 则是错误的]

这样是不是更加简洁明了呢?

上一篇:c语言中统计文件行数


下一篇:c语言中使用程序读取文件