C语言作为一门面向过程的语言,那么他的代码块一般是以函数为最小单位的,我们了解过栈帧之后都知道,代码也是有地址的,那么存放代码地址的变量就叫做函数指针变量。
对于一个函数而言,函数名或者&函数名都代表的是这个函数的地址。
那么这个地址怎么保存呢?请看下面的代码:
void test()
{
printf("Hello\n");
}
int main()
{
void (*p)() = test;
p();
(*p)();
return 0;
}
这样我们就可以使用函数指针p来调用这个函数,在这里有一点比较特殊的地方,我们可以通过*解引用调用,也可以直接用指针名称来调用。
特别强调,函数指针不可以用来做加减运算,我们都知道,指针做加减时,会加上或者减去其指向类型的大小,但是函数的大小计算起来很不方便,而且这样的加减没有意义,所以C语言语法规定不能进行函数指针的加减运算,否则编译器会直接报错!
好了,讲清楚了基本概念,我们来看一点有意思的代码:
//代码1
(*(void (*)())0)();
//代码2
void(*signal(int, void(*)(int)))(int);
来看代码1,先看优先级最高的部分void(*)(),这是一个函数指针,那么给0前面加一个数据类型代表了什么意思呢?当然是把0强制转换成函数指针类型,然后在把他的外壳加上,可以得出结论,这是一个把0强制转换成函数指针的函数调用。
搞明白代码1之后来看代码2。依然是先看