C语言函数指针和指针函数

函数指针和指针函数

指针函数和函数指针的使用以及区分:


指针函数

指针函数,简而言之就是一个返回指针的函数
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));

}

以上是我的个人总结
如有说错或有疑惑,请批评指正!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小昭dedug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值