一、什么是函数指针?
函数指针是存放函数地址的指针变量
如何获得函数的地址?
1.&函数名:和其他数据获得地址一样,通过&函数名即可获得地址
2.函数名:函数名本身值也是函数的地址
int Add(int x, int y) { return x + y; } int main() { printf("%p\n", &Add); printf("%p\n", Add); return 0; }
函数指针的类型是什么?
以 int Add(int x, int y)函数为例,代码如下
函数指针的类型是:int(*)(int, int)
(*)表示p/q是一个指针变量
后面的(int,int)表示函数的参数类型
前面的int表示函数的返回值类型
int Add(int x, int y) { return x + y; } int main() { int(*p)(int, int) = &Add; int(*q)(int, int) = Add; printf("%p\n", p); printf("%p\n", q); return 0; }
二、函数指针如何使用?
解引用函数指针变量 或 直接使用函数指针变量
1.解引用函数指针变量:
解引用函数指针变量就是得到函数名,(*p)等价于Add
2.直接使用函数指针变量:
正常情况下,使用函数是 函数名(参数),我们知道函数名的值是函数地址,而指针变量的值也是函数的地址,那么是否可以直接用指针变量(参数)来调用函数呢?
当然可以!直接使用p(3,5),代码如下:
int Add(int x, int y) { return x + y; } int main() { int(*p)(int, int) = &Add; int ret1 = (*p)(3, 5); int ret2 = p(3, 5); printf("%d\n", ret1); printf("%d\n", ret2); return 0; }
三、分析一行有趣的代码
该行代码的意思是:解引用函数指针进行函数调用
void (*)() 是一个函数指针类型,该函数参数为空,返回值类型为void
将void (*)() 放入括号中,(void (*)())是强制类型转换,(void (*)())0 即将0强制类型转换为函数指针类型
(*(void (*)())0) 即解引用该函数指针,得到是函数名
(*(void (*)())0) () 即函数名(),即使用函数,函数参数为空,无需传参
int main() { (*(void (*)())0)(); return 0; }