• (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
  • 相关阅读:
    有向图的强连通分量
    找不到msvcp120.dll怎么办?msvcp120.dll修复方法分享!
    java里面List<Object>转map,List<String>
    企业数据治理价值解读与场景实践
    组网神器WireGuard安装与配置教程(超详细)
    新的 Work Node 如何加入 K8s 集群 - Kubeadm ?
    Leetcode 22. 括号生成
    后端的datetime类型数据转为string作为(vue)前端的时间YYYY-MM-DD HH:mm:ss
    k8s之容器内存与JVM内存
    Linux-管道、环境变量、常用命令
  • 原文地址:https://blog.csdn.net/qq_43199575/article/details/133125765