• 【C++】函数指针 ④ ( 函数指针做函数参数 | 使用函数指针间接调用函数 | 函数指针做参数 | 函数指针类型的本质 | 函数指针做参数意义 )







    一、函数指针做函数参数




    1、使用函数指针间接调用函数


    在上一篇博客 【C++】函数指针 ③ ( 函数指针语法 | 函数名直接调用函数 | 定义函数指针变量 | 使用 typedef 定义函数类型 | 使用 typedef 定义函数指针类型 ) 中 , 最后一个示例 , 使用 typedef 定义函数指针类型 如下 :

    // int (int, int) 函数指针类型重命名为 pFun_add
    // 该类型变量可以直接接收 函数名 ( 函数地址 )
    typedef int (*pFun_add)(int, int);
    
    • 1
    • 2
    • 3

    通过该指针类型 , 可以 间接调用 add 函数 ;

    	// 定义函数指针类型变量
    	pFun_add pFun = add;
    	// 通过函数指针间接调用 add 函数
    	pFun(7, 8);
    
    • 1
    • 2
    • 3
    • 4

    如果将 函数指针变量 pFun_add pFun 作为参数 , 传递给函数 , 在函数内部可以调用其它函数 , 调用的函数可以动态指定 ;


    2、函数指针做参数


    定义了 如下 函数指针类型 pFun_add , 其类型为 int (*)(int, int) , 该指针指向一个 类型为 int (int, int) 的 函数 ;

    // int (int, int) 函数指针类型重命名为 pFun_add
    // 该类型变量可以直接接收 函数名 ( 函数地址 )
    typedef int (*pFun_add)(int, int);
    
    • 1
    • 2
    • 3

    定义函数 接收 pFun_add 类型的形参作为参数 , 该类型是 函数指针类型 , 也就是 函数接收一个 函数指针类型参数 , 在该函数中调用 函数指针 指向的 函数 ;

    // 传入函数指针, 使用传入的函数进行计算
    int caculate(pFun_add fun, int x, int y) {
    	printf("使用 fun 函数计算 x 和 y = %d\n", fun(x, y));
    	return fun(x, y);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定义 caculate 函数时 , 只定义了 在函数体内部 要调用 int (int, int) 类型的函数 , 具体是什么函数 , 需要在运行时 , 动态传入 ;

    函数指针类型 的该用法 是框架的基础 , 将 函数执行逻辑 与 软件框架 进行解耦 ;

    也就是 将 任务调用者 与 任务实现者 进行了隔离 , 解耦合 ;


    下面的示例中 , 可以将 函数指针类型变量 pFun_add pFun = add 传入函数作为参数 , 也可以直接将 add 函数名 ( 函数地址 ) 作为 函数指针 参数 传递给函数 ;

    	// 定义函数指针类型变量
    	pFun_add pFun = add;
    	// 通过函数指针间接调用 add 函数
    	pFun(7, 8);
    
    	// 将 函数指针 作为参数传递到函数中
    	caculate(pFun, 9, 10);
    
    	// 可以直接将 函数名 ( 函数地址 ) 作为 函数指针 参数 
    	// 传递给函数
    	caculate(add, 11, 12);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、函数指针类型的本质


    函数指针类型 本质 : 提前对任务 格式 进行约定 ;

    • 函数参数类型 约定了 函数的 参与者 ;
    • 函数返回值类型 约定了 函数的 执行结果 ;

    只要 将 子任务 按照 上述 " 函数指针类型 " 的约定 , 开发出 符合要求 的 函数 , 就可以将其作为一个 子任务 传递到 其它函数中执行 ;


    4、函数指针做参数意义


    函数指针做参数意义 :

    • 提高程序灵活性 : 通过使用函数指针作函数参数 , 这样可以 在 程序 运行时 动态地 设置 要调用的函数 , 提高了程序的灵活性 ;
    • 作为回调函数 : 函数指针 可以作为 回调函数 ; 先将 函数指针变量 作为 实参 传递给 其它函数 , 在 接收函数指针 的函数内部 , 满足某种条件时直接调用该函数指针 指向的 函数 , 这样实现了回调 ;
    • 解耦 任务调用 与 任务实现 : 厂商提供 任务实现 , 系统集成商 调用 厂商实现的任务 , 此时 系统集成商 只需要写好 软件框架 , 调用 厂商提供的 任务实现即可 ;
    • 更好的代码组织 : C 语言 中模拟面向对象用法 ; 可以将特定的 函数指针类型 定义为 结构体 的一部分 , 并使用该 结构体 来传递具有特定行为的对象的地址 ; 该操作有助于更好地组织代码 , 使代码更易于理解和维护 ;
    • 错误处理 : 使用函数指针 , 将错误处理函数作为参数传递给其他函数 , 在发生错误时立即调用适当的错误处理函数 , 无需返回到调用堆栈中的较高层次 ;




    二、代码示例 - 函数指针做函数参数



    代码示例 :

    #include "iostream"
    using namespace std; 
    
    // int (int, int) 函数指针类型重命名为 pFun_add
    // 该类型变量可以直接接收 函数名 ( 函数地址 )
    typedef int (*pFun_add)(int, int);
    
    int add(int x, int y) {
    	printf("x + y = %d\n", x + y);
    	return x + y;
    }
    
    // 传入函数指针, 使用传入的函数进行计算
    int caculate(pFun_add fun, int x, int y) {
    	printf("使用 fun 函数计算 x 和 y = %d\n", fun(x, y));
    	return fun(x, y);
    }
    
    int main() {
    
    	// 定义函数指针类型变量
    	pFun_add pFun = add;
    	// 通过函数指针间接调用 add 函数
    	pFun(7, 8);
    
    	// 将 函数指针 作为参数传递到函数中
    	caculate(pFun, 9, 10);
    
    	// 可以直接将 函数名 ( 函数地址 ) 作为 函数指针 参数 
    	// 传递给函数
    	caculate(add, 11, 12);
    
    	// 控制台暂停 , 按任意键继续向后执行
    	system("pause");
    
    	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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    执行结果 :

    x + y = 15
    x + y = 19
    使用 fun 函数计算 x 和 y = 19
    x + y = 19
    x + y = 23
    使用 fun 函数计算 x 和 y = 23
    x + y = 23
    Press any key to continue . . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

  • 相关阅读:
    设计模式复习
    java毕业设计“传情旧物”网站mybatis+源码+调试部署+系统+数据库+lw
    3. 该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定
    面试篇-Java-5+设计模式
    JOSEF电流继电器 DL-33 整定范围0.5-2A 柜内安装板前接线
    CSS伪类使用详解
    归并排序含非递归版
    vlan的学习笔记2(vlan间通信)
    Unity做360度全景预览
    C语言内存函数超详细讲解
  • 原文地址:https://blog.csdn.net/han1202012/article/details/134376159