函数指针:指向函数的指针!
存放函数地址的指针
&函数名-取到的就是函数的地址
数组名(数组首元素的地址) != &数组名(一整个数组的地址)
函数名 == &函数名 -> 两者等价
int Add(int x,int y){return x+y;}int(*pf) (int, int) = &Add;//pf就是一个函数指针变量int(*pf)(int, int) = Add;//也可以这样定义,可得&Add == Addint ret = (*pf)(2,3);//正确int ret = pf(2, 3);//正确,说明函数指针使用时的*是个摆设,有没有都可以int ret = Add(2, 3);int ret = *pf(2, 3);//错误,pf会先跟小括号结合,再解引用
调用0地址的函数
( * (void(*)())0)(); -> 调用0地址处的函数,该函数无参,返回类型是void
void(*)() - 函数指针类型(void(*)())0 -对数字0进行强制类型转换,被解释为一个函数地址: * (void(*)())0 -对0地址进行了解引用操作(* (void(*)())0)() -调用0地址处的函数
参数是函数指针类型的函数指针
void (* signal (int, void(*) (int) ) ) (int) ;
signal 和()先结合,说明signal是函数名signal函数的第一个参数的类型是int,第二个参数的类型是函数指针,该函数指针指向一个参数为int,返回类型是void的函数signal函数的返回类型也是一个函数指针,该函数指针,指向一个参数为int,返回类型是void的函数
并且signal是一个函数的声明
函数指针typedef的使用
错误:typedef void(*) (int) pfunt; //想通过typedef来重命名函数指针,但这种写法报错
正确:typedef void (* pfun_t)(int) ; //正确写法,对void(*)(int)的函数指针类型重命名为pfun_t
void (* signal (int, void(*) (int) ) ) (int) ; ->可由下面两条语句组成
1.typedef void (*pfun_t)(int) ;
2.pfun_t signal(int, pfun_t);
函数指针数组
函数指针数组 - 存放函数指针的数组
int (*pf1) (int, int) = Add;int (*pf2) (int, int) = Sub;int (*pfArr[2] ) (int, int) = {Add,Sub} ; //pfArr就是函数指针数组
该函数指针数组有种跳板的作用,《C和指针》中把其称为转移表
指向(函数指针数组)的指针
函数指针数组
&函数指针数组 -> 取出函数指针数组的地址
int(*p)(int,int);//函数指针int(* p2[4])(int,int);//函数指针的数组int(*(*p3)[4])(int,int) = &p2;//取出的是函数指针数组的地址,int(*)(int,int)是函数指针数组的元素类型
p3就是一个指向【函数指针数组】的指针