对于函数想必大家早已感觉不是很陌生,指针现如今也有着自己独特的了解与认识,但是,对于函数指针不知道屏幕前的您,又能了解多少呢???
对于函数指针,顾名思义,就是指向函数的指针!
1.指向函数的指针变量:
函数的指针是指函数的入口地址,和数组名代表数组的首地址一样,函数名代表函数的入口地址!若有一个指针变量,存放某一个函数的入口,我们可以通过指向这个函数的指针变量来调用函数!
指向函数的指针变量一般定义为: 类型说明符 ( * 指针变量名 )( )
上述的类型说明符是指:指针变量所指向的函数返回值的类型!列 如: int ( * p)( );
定义了一个指向函数的指针变量p,它就可以存放一类整型函数的入口地址,主程序中把一个函数的入口地址赋值给它,它就指向哪一个函数!
下面请看代码:
#include <stdio.h> int add(int x, int y) { return x + y; } int main() { int arr[10] = { 0 }; printf("%p\n", &arr); printf("%p\n", arr); printf("\n"); printf("%p\n", add); printf("%p\n", &add); return 0; }
上面代码就是将数组名与&数组名,相比较,代码的运行结果为:
大家可以看上面代码的运行结果:答案是显而易见的,对于笔者的专门分开,并将其类比!希望大家可以看出来结果!!
&arr 取出的是整个数组的地址,而 arr是数组名,数组名是数组首元素的地址!!
因此:&add 与 add都是函数的地址,没有什么区别!
对于上述代码进行完善:
#include <stdio.h> int add(int x, int y) { return x + y; } int main() { //int arr[10] = { 0 }; //int(*p)[10] = &arr; int (*pf)(int x, int y) = &add; int sum = (*pf)(3, 5); printf("sum=%d\n", sum); return 0; }
上述代码中,pf就是函数指针变量!
在定义pf的类型的时候,我们借鉴了上面的int(*p)[10] = &arr; 所以显得简单化了!
对于上述代码的运行结果为:
上述代码的可更改部分为:
(int ,int ) add int (*pf)(int x, int y) = &add; int sum = (*pf)(3, 5); pf(3 , 5) add(3 , 5)
借鉴上述代码,对于函数指针的定义我们可以用以下的代码概述:
int test(const char* str, double d) { } int main() { int (*pt)(const char*, double) = &test; int (*pt)(const char* str, double d) = &test; }
思考一下:对于下列代码:出自于《C陷阱与缺陷》:如何去思考!
( * (void(*)( ))0( )
上述代码:一句话,可以概述为:
把0直接转化为void(*)()的函数指针,然后去调用0地址出的函数!
void(*)函数的指针类型
( void(*)())0 :把0当作一个函数的地址
把0 强制类型转化为:void (*)()类型的函数!!