函数指针
首先看一段代码找到函数的地址
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Add(int a, int b) {
return a + b;
}
int main() {
int a = 2;
int b = 3;
printf("%p\n", Add); //005811C2
printf("%p\n", &Add); //005811C2
getchar();
return 0;
}
程序运行后可得知Add和&Add都代表函数的地址
printf("%p\n", Add); //005811C2
printf("%p\n", &Add); //005811C2
存放函数的指针
int (*p)(int, int) = &Add;
p因为()的原因,首先和*结合,成为指针类型,p指向参数为( int , int ),范围值为int类型的函数.
int *p():p先和()结合,成为函数,返回类型为int *
和数组指针有点类似,p1指向的是10个元素的地址,元素都是int类型
int arr[10] = { 0 };
int(*p1)[10] = &arr;
函数指针类型 int (* )(int ,int)
数组指针类型 int( * )[10];
使用函数指针调用函数
printf("%d\n", p(a, b));
printf("%d\n", (*p)(a, b));
printf("%d\n", (***p)(a, b));
*两个执行的结果相同,p是函数指针,p是调用这个函数,其实直接用p进行调用也行,可对比上面的Add和&Add都代表函数的地址。
其实p前面有多少*无所谓,执行结果都一样
其他类型函数的指针
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void Print(const char* str) {
printf("%s", str);
}
int main() {
const char* str = "abcdef";
void (*ps)(const char* str) = &Print;
ps(str);
getchar();
return 0;
}
下面分析两块代码
代码1
(*(void(*))0)();
可以拆分为
( *( void(*)() )0 ) ();
void()()是函数指针类型,加上(),( void( * )() ) 0,是将0处的地址强制类型转换成void()()类型,
( * ( void( * )() )0)()后前面的 * 进行解引用操作,执行这个地址的函数,后面的()是这个地址的函数没有参数。
代码2
void (*signal(int, void(*)(int)))(int);
进行拆分
signal( int, void(*)(int))
signal先后和后面的()结合形成函数
函数的第一个参数是int ,类型,第二个参数是void(*)(int)类型
void(*)(int)
signal函数饿返回类型是void(*)(int)函数指针类型。
使用typedef 对函数指针重命名,将void(*)(int)命名为pfu_t
typedef void(*pfu_t)(int)
所以代码2可改成:
pfu_t signal(int ,pfu_t)