• (c/c++)——函数指针(回调函数)



    前言

    函数的二进制代码存放在内存四区中的代码段,函数的地址是它在内存中的起始地址(即每个函数都有一个入口地址)。函数指针就指向这个起始地址,将函数指针作为参数,就可以调用该函数


    一、使用函数指针的三个步骤

    1. 声明函数指针
      普通指针,需要给它一个类型,如 int* a 或 char* a ;同理,函数指针也需要给它一个类型。这个类型指的是函数的返回值参数类型和顺序(函数名和实参名不是。可以这样理解,指针是指向一个地址,取什么名字都行,只是一个名称罢了)

    如果函数原型为:

    // 下面两个函数的返回值、参数类型和顺序一样
    int func1(int a,string str);
    int func2(int b,string name);
    
    bool func3(int age,string name);
    
    bool func4(int age);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    函数指针为(注意以下两点)

    int (*func)(int a,string str);
    
    bool (*pfunc3)(int ,string); // 1、形参可以不写,只保留类型即可
    
    bool (*pf4)(int);  // 2、指针名无所谓,随便自己定义一个都行(但不要和函数名相同)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 初始化函数指针
      声明了函数指针,肯定要让它指向函数的入口地址,而函数名就是这个地址,所以初始化如下:
    函数指针名 = 函数名
    pfunc3 = func3  // 如果函数指针名与函数名相同,这里就会出现歧义
    
    • 1
    • 2
    1. 使用函数指针调用函数
    (*函数指针名)(实参);  // c/c++通用,推荐使用这个
    函数指针名(实参);  // c++
    (*pfunc3)(实参1,实参2);
    
    • 1
    • 2
    • 3

    二、应用场景——回调函数

    函数指针最常用的方式就是回调函数,这在多线程和网络通讯中很常见

    那回调函数是什么意思呢?
      简单来说,就是在一个主体函数中调用另一个功能函数。

    那为什么要这样做,而不是直接把该功能函数写进主体函数里?
      因为功能函数的种类可以有很多,假设主体函数是输入一串数字,然后按照一定的规则排序,最后再输出排序后的数字。这里的规则有很多,比如从大到小,从小到大,从中间开始到大再到小等等,可以把这些规则都写进主体函数中,在明确要使用哪个规则,但这样主体函数的代码量就会非常多。这时就可以使用回调函数:把排序规则在外面写成一个功能函数,想要哪种排序就写哪种,然后使用函数指针让主体函数来调用自己写的规则函数即可。

    示例代码:

    #include 
    using namespace std;
    
    void func1(string a){  cout <<"升序" << a << endl;}
    void func2(string a){  cout <<"降序" << a << endl;}
    void func3(string a){  cout <<"中间排序" << a << endl;}
    
    void sort(string n, void (*pfunc)(string))  // 1、声明函数指针
    {
        cout <<"将一串数字:"<<n<<"解析为多个数字"<<endl;
    
        (*pfunc)(n);  // 调用函数
    
        cout << "返回排序后的数字" << endl;
    }
    
    int main()
    {
        string num = "348963";
    
        sort(num, func1);  // 2、函数指针赋值
        // sort(num, func2);
        // sort(num, func3);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    GSCoolink GSV6183 带嵌入式MCU的MIPI D-PHY 转 DP/eDP
    C++入门学习(3)函数重载
    你找到适合自己的赚钱门路了吗
    ESP32C3 LED PWM使用和ESP32差异说明
    ElementUI图标少,引入阿里矢量图标
    【USB设备设计】-- CDC 设备开发(虚拟串口设备)
    【数据库】形式化关系查询语言(一):关系代数Relational Algebra
    2022.10.29每日一题
    IDC服务器商是如何保护服务器的数据安全
    Vue3 中有场景是 reactive 能做而 ref 做不了的吗?
  • 原文地址:https://blog.csdn.net/qq_43199575/article/details/133125765