前言:
为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。
1. 函数指针的定义
函数的指针,它是一个指针,指向一个函数。
举例:
A:char *(*func1)(char *p1,char *p2);
B:char * *func2(char *p1,char *p2);
C:char *func3(char *p1,char *p2);
解释:
A:这里 func1 不是函数名,而是一个指针变量,指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是指针。可以理解为:(char *) 类型的指针变量 *func1 。
B:func2 是函数名,带两个参数,返回值为 char ** 类型,是一个二级指针。
C:func3 是函数名,带两个参数,返回值为 char * 类型。
2. 函数指针的运用
测试:
char *func(char *p1, char *p2)
{
int i = 0;
i = strcmp(p1,p2);
if (i == 0)
{
return p1;
}
else
{
return p2;
}
}
调用函数指针:
int main(void)
{
/*定义一个函数指针变量*/
char *(*pf)(char *p1, char *p2);
pf = &func;/*初始化,将函数的地址取出来*/
(*pf)("aa","bb");/*地址是个实际值*/
getchar();
return 0;
}
注:
//定义一个函数指针变量,(*pf) 括号不能省略
eg:int (*pf)funcx(int ,int)
3. *(int *)&p
void FuncPri(void)
{
printf("void func ! \r\n");
}
int main(void)
{
void (*pv)();
*(int *)&pv = (int)FuncPri;
(*pv)();
getchar();
return 0;
}
注解:
(1)void (*pv)():定义一个指针变量 pv,pv 指向一个函数,这个函数的参数和返回值都是 void。
(2)&pv:取指针 pv 本身的地址,在 32 位系统,它为一个 32 位的二进制数。
(3)(int *)&pv:表示将地址强制转换成指向 int 类型的数据。
(4)*(int *)&pv = (int)FuncPri:表示将函数的入口地址赋值给指针变量 pv。那么 (*pv)() 就是表示对函数的调用。
函数指针的作用:
可以将实现同一功能的多个模块统一起来标识,便于后期维护,系统结构更清晰,便于分层设计,利于系统抽象,降低耦合度,使接口与实现分开。
4. ((void() ())0) ()
分析:
(1)void (*)():一个函数指针,无返回值,无参数;
(2)(void(*) ())0:将 0 强制转换成函数指针类型,0 是一个地址,即一个函数存在首地址为 0 的一段区域内。
(3)((void() ())0):取 0 地址开始的一段内存内的内容,内容就是保存在首地址为 0 的一段区域内的函数。
(4)((void() ())0) ():函数调用。
5. 函数指针与指针函数
对比 | 函数指针 | 指针函数 |
---|---|---|
实质 | 一个指针,一个变量,常用来调用函数 | 一个函数,返回值是指针类型的函数,有自己的函数体 |
格式 | 数据类型关键字 *Func(形参),eg:char *Func(void); | 数据类型关键字 (*指针名)(形参),eg:int (*pf)(int,int *); |
通过 typedef 关键字来统一命名函数指针:
形式:形式2:typedef 返回类型(*新类型)(参数表)
typedef int (*pFunc)(int, int); // 声明一个函数指针类型
//返回值为int类型,两个参数为 int 类型
参考: