一、概念
函数指针:指向函数的指针!(存放函数地址的指针)
函数名和&函数名:
数组名!=&数组名
函数名= =&函数名
如何将函数地址存放起来?
跟数组指针很像
首先为了表明它是一个指针,所以先需要(*pf),用括号括起来表示
接着考虑函数的参数类型和返回类型
为什么是函数指针,因为看到了()圆括号,所以就相当于数组指针需要看到【】,标识符!
int (*pf) (int,int)注意后面那个括号里面的内容就是函数的参数类型!
函数指针与其他指针的特殊之处:
调用函数指针时。*解引用操作符可有可无!直接用pf调用也可以!
函数名就是地址。
这是函数指针独有的!
总体思路:
首先确定了(*)是指针,然后向后看,发现是圆括号()就表示这个函数指向的就是函数!最后填写参数类型和返回类型。
二、辨析
1、(*(void(*)())0)();辨析这段代码的意义
int main() { (*(void(*)())0)();//辨析这段代码的含义 //这道题的突破口在于0,0前面有括号表示强制类型转换 // void(*) ()表示函数指针类型 //(void (*)())0表示将0这处的地址转换为函数指针类型 //(*(void(*)())0)()调用0地址处的函数(无返回值,无参类型的函数) return 0; }
这一行代码就是调用一个被强制类型转换的函数指针类型,然后解引用使用这个函数
2、void (signal(int, void()(int))) (int);辨析这段代码的含义
int main() { void (*signal(int, void(*)(int))) (int);//辨析这段代码的含义 //这道题的突破口在于signal后面直接跟括号,因此signal是函数名, //接着我们根据正常分析函数的方法进行分析 int main() //所以函数名后面括号内就是参数,可以看出有两个参数,一个是int类型,另一个是函数指针类型 //接着就剩一个函数的返回类型,因此就剩下 void (*) (int) //可以看出返回类型是一个函数指针类型,分析完毕! void (*signal(int, void(*)(int))) (int); //void (*)(int) signal(int, void(*)(int));//这样写表达含义是与上式一样的,但不合法! //规定:函数的返回类型凡是函数指针类型,需要将函数名和参数嵌套在(*)里面! typedef void(*)(int) pf;//这样写也是不合法的,也是需要将函数名嵌套在(*)里面 typedef void(*pf)(int); pf signal(int, pf);//便捷的定义方式! return 0; }
总结:
无论是声明一个函数(该函数的返回类型为函数指针)还是typedef一个函数指针类型,,都需要将最后结果书写成函数指针的类型!
最重要的还是分析问题的方法,比如上面那道题,看到signal是一个函数名,然后寻找函数的参数和函数的返回类型!