文章目录
大家好,我是安然无虞。
- 博客主页:安然无虞
- 作者介绍:2021年博客新星Top2
- 咱的口号:🌹小比特,大梦想🌹
- 作者请求:由于博主水平有限,博文中难免会有错误和不准之处,我也非常渴望知道这些错误,恳请铁汁批评斧正。
- 火爆专栏:蓝桥杯基础算法剖析
函数指针
看下面一段代码:
#include<stdio.h> void test() { printf("hehe\n"); } int main() { printf("%p\n", test); printf("%p\n", &test); return 0; }
注意:函数名和&函数名都指的是函数的地址,函数和数组不一样,函数没有首元素的概念。
上面输出的都是test函数的地址,试问:如何将test函数的地址保存起来?
void (*pfun)();//pfun先和*结合说明pfun是一个指针,看到外面的'()'说明其指向一个参数为空,返回值也为空的函数
既然函数指针指向的是一个函数,那怎么通过函数指针来调用函数呢?
请看下面一段代码:
#include<stdio.h> int Add(int x, int y) { return x + y; } int main() { int (*pf)(int, int) = &Add;//注意,写成Add也可以,都表示Add函数的地址 //pf是一个指针,指向一个函数,函数参数是int ,int, 返回值也是int int sum = (*pf)(2, 3);//函数调用,这里也可以写成pf(2,3),表示的是一个意思 //写上是方便大家理解 printf("%d\n", sum); return 0; }
两道笔试题
分析下面两条代码:
代码1:
( *(void(*)()) 0 )(); //做这样的题目时,需要学会断句 //1.void(*)()是一个函数指针,用括号将函数指针类型括了起来, //也就是说将0强制类型转化成了函数指针类型 //2.再去调用0地址处,这个参数是无参,返回值是void的函数 //综上,代码1表示的是一次函数调用,调用0地址处的函数
代码2:
void ( *signal (int, void(*)(int)) )(int); //signal先和()结合,说明它是一个函数,但是可能会觉得长相有点奇怪 //直接看肯定看不出来,但是将signal(int, void(*)(int))拿出来之后就一目了然了, //不难发现,signal是一个函数声明,函数参数是int和void(*)int,返回值是函数指针void(*)(int)
注:上面两个代码来自《C陷阱与缺陷》一书。
不过代码2看起来太麻烦,可不可以简化它呢?答案是当然可以。
typedef void(*pfun_t)(int); pfun_t signal(int, pfun_t);
上面就是简化后的代码,这里需要强调的是函数指针使用有些奇怪,
所以我们需要注意区分下面这两条概念:
void(*p)(int);//p是函数指针变量的名字 typedef void(*pfun_t)(int);//pfun_t是类型名
遇见安然遇见你,不负代码不负卿。