C语言进阶:指针的进阶(4)
目录
- 函数指针
- 函数指针的定义
- 函数指针的类型
- 函数指针的使用
- Example
- 总结
函数指针
函数指针的定义
整型指针存放整型的地址;数组指针存放数组的地址;那么类比可得,函数指针存放函数的地址。显然,函数指针指向函数,存放函数的地址。搞懂函数指针,先了解函数的地址。
![C语言进阶:指针的进阶(4)](https://img.it610.com/image/info11/56ab280473974777a8ce8d1db68fbd90.jpg)
文章图片
&函数名或函数名代表函数地址,与&数组名和数组名略有不同,&函数名和函数名完全一致。
函数的地址必然要放到函数指针里,函数指针的类型该如何写呢?(以Add函数为例)
//整型指针int* pa = &a; //字符指针 char* pc = &ch; //数组指针int(*pa)[10] = &arr; //函数指针 - 存放函数地址int(*pf)(int, int) = &Add;
函数指针的类型
int Add(int x, int y); //1.int(*pf)(int, int) = &Add; //2.int *pf(int, int) = &Add;
倘若,去掉括号前文已交代,指针,去掉指针名和*就是指针所指向的变量类型。int* pf(int, int),
pf就变成函数名,返回类型是int*。所以指针必须带括号。
- 整型指针,去掉*和指针名,即为整型变量类型int。字符指针,为字符类型char。数组指针,去掉后为数组类型int[10]。
- 函数指针,去掉*和指针名,即为函数的类型int(int,int)。
- 去掉指针名pf,即为指针类型
int(*)(int, int)
- 去掉指针名pf和*,即为指针所指向的函数类型为
int(int, int)
函数指针的使用
计算机硬件程序经常通过调用地址的方式来调用函数,因此需要使用函数指针调用函数。
int Add(int x, int y){ return x + y; }int main(){//1.int(*pf)(int, int) = &Add; //函数指针指向Add函数//2.int(*pf)(int, int) = Add; //1. int ret = (*pf)(2, 3); //2.int ret = pf(2, 3); printf("%d\n", ret); return 0; }
前面已经交代,&函数名和函数名都是函数的地址,完全等价。所以两种初始化函数指针的方式都可以。既然函数名
Add
可以直接赋值给函数指针pf,说明二者等价。函数指针名pf不解引用也可以使用,*在此处形同虚设,甚至于不写或写多个都并无大碍,仅为理解。既然函数名也是函数地址,所以对其解引用也是可以的。我们甚至可以这样写,但仅限娱乐,没有必要。
Add(2, 3); //1(*Add)(2, 3); //2(*&Add)(2, 3); //3
Example
解释下列代码
//1.(*(void(*)())0)(); //2.void (*signal(int, void(*)(int)))(int);
![C语言进阶:指针的进阶(4)](https://img.it610.com/image/info11/b8407c0d250041ca9e5c43eabfbbfbe9.png)
文章图片
1.
void(*)()
是函数指针类型,放在( )0中,也就是把0强制转换成地址,该地址处存放一个函数其类型为void(*)(void)
。2.这样(
void(*)())0
就变成了指针,指向该地址的函数,且对其解引用访问此函数。3.
(*(void(*)())0)
也相当于(*pf)
,通过函数指针解引用代替函数名,函数名后面带上();
,相当于(*pf)();
也就是一次不传参的函数调用。![C语言进阶:指针的进阶(4)](https://img.it610.com/image/info11/efc83bda8a60433d9e77efe06d078946.png)
文章图片
【C语言进阶:指针的进阶(4)】1.signal先和()结合,说明signal为函数名,其后(int, void(*)(int)),为其参数列表。
2.去掉函数名称和参数列表,剩下的void(*)(int)就是返回类型,所以是一次函数声明。
void (* signal(int, void(*)(int)) ) (int); typedef void(* pf_t)(int); //typedef简化代码pf_t signal(int, pf_t);
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 【生信技能树】R语言练习题|【生信技能树】R语言练习题 - 中级
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- 推荐系统论文进阶|CTR预估 论文精读(十一)--Deep Interest Evolution Network(DIEN)
- C语言解方程的根和判断是否是闰年
- C语言的版本比较
- 普通人进阶的三个过程-很多人都知道,但却本末倒置