• C++——函数指针与指针函数


    函数指针与指针函数

    1. 初识

    在这里插入图片描述
    一个区分的小技巧:
    “函数指针”中函数是用来修饰指针的,所以主体是指针,它主要是用来指向函数的。
    “指针函数”中指针是用来修饰函数的,所以主体是函数,该函数的返回类型是指针。

    举个简单的例子:

    #include
    using namespace std;
    
    int add(int a, int b) {
    	return a + b;
    }
    
    int sub(int a, int b) {
    	return a - b;
    }
    
    //函数指针
    int (*f)(int, int);
    
    //指针函数
    int* multi(int a, int b) {
    	int c = a*b;
    	return &c;
    }
    
    int main() {
    	int a = 3, b = 2;
    	f = add; 
    	cout << f(a, b) << endl;
    	f = &sub;
    	cout << f(a, b) << endl;
    	int* c = multi(a, b);
    	cout << *c << endl;
    	return 0;
    }
    
    输出结果:
    5
    1
    6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    上面代码中,f = add;f = &sub 其实表达的是一个意思,函数指针f分别指向 add 和 sub。上面还有一个小细节,()的优先级比*高

    2. 函数指针

    函数凡是符合函数指针中的格式的,都可以传递给函数指针进行调用,具体说明,可以看下面代码例子。

    函数指针一般用于回调函数、函数回调、函数指针数组等操作,提供了一种灵活的方式来实现动态的函数调用和扩展功能。

    这里需要说明的一点就是回调函数和函数回调的区别
    它们的区别跟“函数指针与指针函数的区别”同理,要看主体。函数回调是一种机制,回调函数是一个函数。在调用某个函数时,不是通过函数名,而是通过函数指针,这种方式就是函数回调,而这个“某个函数”就是回调函数。

    2.1 回调函数和函数回调

    #include 
    using namespace std;
    
    // 定义回调函数
    void callbackFunction(int result) {
        cout << "回调函数被调用,result = " << result << endl;
    }
    
    // 调用回调函数的函数
    void callCallbackFunction(int result, void (*callback)(int)) {
        // 执行一些操作
        cout << "执行一些操作" << endl;
        // 调用回调函数
        callback(result);
    }
    
    int main() {
        // 调用函数并传递回调函数
        callCallbackFunction(123, callbackFunction);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上面代码中callbackFunction就是回调函数,而在callCallbackFunction里面调用函数指针callback去调用回调函数,这种方式就是函数回调。

    回调函数callbackFunction的返回类型是 void ,而参数类型是 int 。函数指针的返回类型也是 void,参数类型也是 int ,所以callbackFunction可以传递给函数指针。

    它有另外一种写法:

    #include 
    using namespace std;
    
    typedef void (*Callback)(int);
    
    // 定义回调函数
    void callbackFunction(int result) {
        cout << "回调函数被调用,result = " << result << endl;
    }
    
    // 调用回调函数的函数
    void callCallbackFunction(int result, Callback callback) {
        // 执行一些操作
        cout << "执行一些操作" << endl;
        // 调用回调函数
        callback(result);
    }
    
    int main() {
        // 调用函数并传递回调函数
        callCallbackFunction(123, callbackFunction);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    typedef void (*Callback)(int); 是一个函数指针类型的定义。让我逐步解释一下这个定义:

    typedef:这个关键字用于给一个数据类型起一个别名,可以通过这个别名来声明变量。
    void:这是函数的返回类型,表示函数没有返回值。
    (*Callback):这是一个函数指针的声明,Callback 是这个函数指针的名称。
    (int):这是函数指针所指向的函数的参数列表,int 表示这个函数接受一个 int 类型的参数。
    综合起来看,typedef void (*Callback)(int); 是一个将函数指针类型命名为 Callback 的语句。它定义了一个函数指针类型,该函数指针可以指向一个返回值为空(void)的函数,该函数接受一个 int 类型的参数。

    通过使用这个类型定义,我们可以方便地创建符合该函数指针类型的函数指针变量。例如,可以定义一个函数指针变量 Callback callback;,然后将其指向一个满足上述函数指针类型要求的函数,以便在需要时进行回调操作。

    使用 typedef 可以简化代码,使代码更加易读和易于维护,提高了代码的可读性和可移植性。

    2.2 函数指针数组

    #include 
    
    // 函数指针类型
    typedef void (*PrintFunc)();
    
    // 打印函数示例
    void printHello() {
        std::cout << "Hello ";
    }
    
    void printWorld() {
        std::cout << "World!";
    }
    
    int main() {
        // 声明函数指针数组
        PrintFunc printFuncArray[] = { printHello, printWorld };
    
        // 遍历函数指针数组并调用函数
        for (int i = 0; i < sizeof(printFuncArray) / sizeof(printFuncArray[0]); ++i) {
            printFuncArray[i]();
        }
    
        std::cout << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在上面的示例中,首先声明了一个函数指针类型 PrintFunc,它是一个指向返回类型为 void,不接受参数的函数指针。然后,我们定义了两个打印函数 printHello() 和 printWorld()。接下来,在 main 函数中,我们声明了一个函数指针数组 printFuncArray,其中存储了这两个打印函数的地址。最后,我们遍历函数指针数组,并通过函数指针调用函数来打印 “Hello World!”。

    3. 指针函数

    #include 
    
    // 指针函数的原型
    int* createArray(int size);
    
    int main() {
        int size = 5;
        
        // 调用指针函数,分配内存并返回指针
        int* ptr = createArray(size);
        
        // 使用指针访问动态分配的数组
        for (int i = 0; i < size; ++i) {
            ptr[i] = i + 1;
        }
        
        // 打印数组元素
        for (int i = 0; i < size; ++i) {
            std::cout << ptr[i] << " ";
        }
        
        // 释放动态分配的内存
        delete[] ptr;
        
        return 0;
    }
    
    // 指针函数的定义
    int* createArray(int size) {
        return new int[size];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    总结: 指针函数在 C++ 中常用于动态内存分配、返回动态数据结构等场景。通过返回指针,我们可以在函数外部访问和操作函数内部动态分配的数据。需要注意的是,使用指针函数时要小心管理内存,避免内存泄漏和悬空指针等问题。

  • 相关阅读:
    十个经典java开发项目及其描述-马上写到你的简历中去吧,祝你升职加薪
    Linux——文件编程:写整数、结构体到文件
    L2-013 红色警报(Python3)
    常用数学分析和建模软件
    在排序数组中查找元素的第一个和最后一个位置
    系统架构师论文总结【持续更新】
    Spring Boot如何配置CORS支持
    分享一个基于微信小程序的高校图书馆预约座位小程序 图书馆占座小程序源码 lw 调试
    Jupyter notebook如何显示目录(动图演示)
    使用Docker Compose搭建WordPress博客
  • 原文地址:https://blog.csdn.net/weixin_45604295/article/details/133419434