一、函数指针
函数指针也只是一个普普通通的指针,不过它指向的对象变成了函数,或者说它存储的是函数的地址
我们都知道,int *pp=&a;,我们把指针(*p)去掉后,剩下的int就是指针所指向对象的类型,而在函数指针中,函数的类型由它们的返回类型以及函数参数决定,
1.1开胃小菜
函数名和&函数名是等价的,它们表示的都是函数的地址,验证如下
1.2函数指针的定义
(函数返回类型)(*指针名)(函数参数);
1.3函数指针的创建与初始化
如上代码,我们创建了两个函数,现在我们可以用两个函数指针来分别指向这俩个函数
我们分别创建两个指针变量p1,p2,都是指针,所以和*结合,即(*p1),(*p2),
因此,我们可以使用如下代码完成对函数指针的初始化,即
当我们输出两个函数和函数指针的地址时,会发现它们是相同的
1.4函数指针的调用
我们在开头提到,函数名和&函数名是等价的,我们再来看看函数指针的创建与初始化,int (*p2)(int)=&test2;这条语句就等价于int (*p2)(int)=test2;
这里的p2也等价于test2(上图可知),因此我们在调用test2函数时,也可以用函数指针,因为test2(3)就等价p2(3)
我们再定义一个整型来接收函数的返回值,具体如下
1.5初露锋芒
(*(void (*)())0)();//我们来分析一下这行代码代表的含义
1.void (*)():一个函数指针类型
2.(void (*)())0):把0强制转化为函数指针所指向函数的地址,也就是说此处代表一个函数地址
3.(*(void (*)())0)():解引用调用该函数
具体解释
//当你看到void (*)()时有没有很眼熟,
当我们写成void (*p)()时是不是创建了一个函数指针p,p指向的是一个返回类型为空,函数参数为空的函数,那么 void (*)()是不是指针p的类型(p就是个地址),同时也是该函数的地址,而(void (*)())0)就代表把0强制类型转化为该函数的地址,说明白一点(void (*)())0)表示的就是一个函数的地址
再加上*就表示调用该函数
1.6大展身手
void (*signal(int , void(*)(int)))(int)//我们来分析一下这行代码代表的含义
1.signal(int , void(*)(int))
()的优先级高于*,signal先和()结合,代表一个函数,该函数参数一个为int类型,一个为void(*)(int)类型(函数指针类型,该函数指针指向的是一个返回类型为void,函数参数为int的函数
2.void (*)(int):去掉函数名和函数参数后,剩下的是函数的返回类型,显然,
signal函数的返回类型是函数指针类型
二、函数指针数组
存放函数指针的数组
int arr[10]={0};定义了一个数组arr,去掉arr[10]后剩下的int代表数组元素的类型
int (*p[10])();
代码解析:[]的优先级高于*,p先和[]结合,是一个数组,去掉p[10],剩下int (*)(),表示数组p的元素类型为函数指针