函数指针和指针函数
指针函数和函数指针的使用以及区分:
指针函数
指针函数,简而言之就是一个返回指针的函数
int funtion(); 返回整型变量
int *funtion1(); 返回指向整型变量的指针
函数指针
函数指针,说白了就是一个指向函数的指针。函数指针?是的,程序中的每一个函数都位于内存中的某一个位置,所以存在指向那个位置的指针是完全有可能。
int f(int a)
{
return a;
}
//简单声明一个函数指针并不意味着马上就可以使用,和其他指针一样,对函数指针访问之前必须把它初始化为指向某个函数,才能使用。
int (*p)(int) = &f;
//函数指针的定义并初始化 定义一个指向 返回值为整型且传入一个整型参数 的函数类型的指针
int ans;
//三种方式调用函数
ans = f(25);
//1编译器会把它转换成函数指针
ans = (*p)(25);
//2它把函数指针转换为一个函数名。这个转换并不是真正需要的,因为编译器在执行函数调用操作符之前又会把它转换回去。这个函数的效果就和前一句是一样的
ans = p(25);
//3间接访问操作并非必须,因为编译器需要是一个函数指针。
为了能更好的理解指针函数和函数指针的区分
举些栗子:
int* f()// 首先执行的是函数调用操作符,因为它的优先级高于间接访问操作符,所以是函数
int (* f)(); //函数指针
int * (* f)(); //和前面的基本一样,f也是一个函数指针,只是所指向的函数的返回值是一个整型指针
为什么要使用函数指针呢?
有不少人就觉得,本来简单的函数调用,搞得那么复杂干什么?其实在这样比较简单的代码实现中不容易看出来的,的项目比较大,代码变得复杂了以后,函数指针就体现出了优越性。举个栗子,如果我们实现数组的排序,常用的排序方法有很多种,例如:冒泡,选择,快排,插入等。你会发现,其实他们除了函数名不同之外,他们的返回值和传入的参数是一样的。这时候我们需要调用不同的排序方法,就可以使用函数指针函数来实现,我们只需要修改函数指针初始化的地方,而不需要去修改每个调用的地方。
回调函数
函数指针的一个典型的应用就是回调函数。
什么是回调函数?
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数出传递给另一个函数,当这个这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于该事件或条件响应。
简单点就是建立一个类似的东西,比如算法库,有冒泡 ,选择等
以下是从网上找到的栗子
#include <stdio.h>
typedef struct _OP{
float (*p_add)(float ,float );
float (*p_sub)(float ,float );
float (*p_mul)(float ,float );
float (*p_div)(float ,float );
} OP;//定义函数指针结构体
float ADD(float a,float b)
{
return a+b;
}//加法函数
float SUB(float a,float b)
{
return a-b;
}//减法函数
float MUL(float a,float b)
{
return a*b;
}//乘法
float DIV(float a,float b)
{
return a/b;
}//除法
void init_op(OP *op)
{
op->p_add=ADD;
op->p_sub=SUB;
op->p_mul=&MUL;
op->p_div=&DIV;
}//对函数指针初始化
float add_sub_mul_div(float a,float b,float (*abc)(float,float))
{
return (*abc)(a,b);
}//回调函数,仔细看该函数的参数,并反复看前面粗体文字回调函数的定义
int main(int argc, char *argv[])
{
OP *op = (OP *)malloc(sizeof(OP));//分配内存空间
init_op(op);
/* 直接使用函数指针调用函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", (op->p_add)(1.3, 2.2), (*op->p_sub)(1.3, 2.2),
(op->p_mul)(1.3, 2.2), (*op->p_div)(1.3, 2.2));
/* 调用回调函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n",
add_sub_mul_div(1.3, 2.2, ADD),
add_sub_mul_div(1.3, 2.2, SUB),
add_sub_mul_div(1.3, 2.2, MUL),
add_sub_mul_div(1.3, 2.2, DIV));
}
以上是我的个人总结
如有说错或有疑惑,请批评指正!