函数指针与回调函数

函数指针

1.前言
  1. 函数类型

    1. 函数有自己的特定类型,且由返回值参数类型参数个数共同决定(隐含了参数顺序)

      例如:int add(int i, int j)的类型为int(int, int)

    2. 通过typedef为函数重命名typedef type name(parameter list)

      例如:typedef int f(int, int)type void p(int)
      解释:定义函数f,返回值为int类型,参数有两个都为int类型,

1.函数指针
  1. 说明:

    1. 函数指针用于指向一个函数
    2. 函数名是指向执行函数体的入口地址
    3. 可以通过函数类型定义函数指针:Func Type* pointer;
    4. 也可以直接定义:type (*pointer) (parameter list);

    1. pointer为函数指针变量名
    2. type为指向函数的返回值类型
    3. parameter list为指向函数的参数类型列表
  • 示例:

  • typedef int(FUNC)(int);  //定义返回值为int,参数为一个int类型的函数类型
    
    int test(int i)
    {
        return i * i;
    }
    
    void f()
    {
        printf("Call f()......\n");
    }
    
    int main()
    {
        FUNC *pt = test;  //定义一个函数指针pt存放test函数的地址
        void(*pf)() = &f;  //直接定义函数指针pf存放f函数的地址(为了兼容以前的编译器版本)
    
        pf();  //调用函数
        (*pf)();  //调用函数
        printf("Call : %d\n", pt(2));
        return 0;
    }
    2.回调函数
    1. 机制原理:

      1. 调用者不知道具体事件发生的时候需要调用的具体函数
      2. 被调函数不知道何时被调用,只知道被调用后要完成的任务
      3. 当具体事件发生时,调用者通过函数指针调用具体函数
    2. 示例:

    typedef int(*FUNCTION)(int);  //定能一个返回值为int,有一个参数为int类型的函数指针类型
    
    int g(int n, FUNCTION f)
    {
        /*传递参数为FUNCTION类型的f (不知道将会用到什么类型)*/
        int i = 0;
        int ret = 0;
    
        for(i = 0; i < n; ++i)
        {
            /*在遇到具体情况时调用具体的函数*/
            ret += i * f(i);
        }
    
        return ret;
    }
    
    int f1(int x)
    {
         return x + 1;
    }
    
    int f2(int x)
    {
         return 2 * x - 1;
    }
    
    int f3(int x)
    {
         return -x;
    }
    
    int main()
    {
        /*调用g函数,遇到三种不同的情况,分别处理*/
        printf("x * f1(x): %d\n", g(3, f1));
        printf("x * f2(x): %d\n", g(3, f2));
        printf("x * f3(x): %d\n", g(3, f3));
        return 0;
    }
    • 注:在处理程序时,可以进行模块化,使两个模块间不相互依赖
    3.指针阅读技巧
    • 左右法则:

      1. 从最里层(左边)的圆括号中未定义的标识符看起
      2. 先往右看,再往左看
      3. 当遇到圆括号或者方括号时可以确定部分类型,并调转方向
      4. 重复2,3步骤,直到结束
    • 示例:

    int (*func)(int *)
    
    /*编译器的处理*/
    
    /*
    第一步:找到未定义的标识符 (func),在这里(int*)已经有定义了,而(func)是我们自定义的标识符,而且没有被定义(因为不知道是什么类型的)
    
    第二步:往右看看到了圆括号,往左看看到了*,确定func为一个指针,然后处理得到
    int (int *)
    
    第三步:往右看看到了圆括号,那么可以确定func为一个函数指针,它的参数为一个int指针类型的,然后往左看,看到int,那么确定返回的类型为int类型的
    */
    
    int main()
    {
        int (*p2)(int *, int (*f)(int *));
        /*首先找到p2,然后找到*p2,然后判断p2指向函数,
        然后看到第二个参数找到一个未定义的f,然后找到*f,然后找到f指向函数,
        然后找到f指向的函数有一个参数为int*类型的,然后找到f指向的函数的返回值为int类型,
        然后找到p2指向的函数有两个参数为int*和指向函数的指针,然后找到p2指向的函数的返回值为int类型的*/
    
        int (*p3[5])(int*);
        /*用上述方法得到p3为一个包含5个元素的数组,
        每个元素都是一个函数指针,
        函数指针指向的类型为int(int*)*/
        return 0;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值