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

文章目录

  • 一、函数指针做函数参数
    • 1、使用函数指针间接调用函数
    • 2、函数指针做参数
    • 3、函数指针类型的本质
    • 4、函数指针做参数意义
  • 二、代码示例 - 函数指针做函数参数






一、函数指针做函数参数




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


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

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

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

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

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


2、函数指针做参数


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

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

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

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

定义 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);

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;
}

执行结果 :

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 . . .

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/140689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

说说React Jsx转换成真实DOM过程?

一、是什么 react通过将组件编写的JSX映射到屏幕,以及组件中的状态发生了变化之后 React会将这些「变化」更新到屏幕上 在前面文章了解中,JSX通过babel最终转化成React.createElement这种形式,例如: <div> < img src="avatar.png" className="…

VS Code设置技巧

基础设置 中文界面 安装扩展&#xff1a;Chinese(Simplified) Language Pack 自动换行 文件 - 首选项 - 设置&#xff0c;搜索wrap&#xff0c;找到Editor: Word Wrap&#xff0c;将其更改为on。

【数据结构】非递归实现二叉树的前 + 中 + 后 + 层序遍历(听说面试会考?)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&…

如何在OpenWrt上部署uhttpd搭建web服务器,并实现公网远程访问

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

数据分析 - 思考题

上班路上刷到的有趣题

BEVFusion简介、环境配置与安装以及遇到的各种报错处理

BEVFusion简介、环境配置与安装以及遇到的各种报错处理 BEVFusion简介BEVFusion环境配置与安装报错解决 BEVFusion简介 针对点云投射到图像的多模态融合和图像投射到点云的多模态融合&#xff0c;前者会损失空间几何信息&#xff0c;后者会损失图像语义信息&#xff0c;这两种…

DMDEM部署说明-详细步骤-(DM8达梦数据库)

DMDEM部署说明-详细步骤-DM8达梦数据库 环境介绍1 部署DM8 数据库1.1 创建一个数据库作为DEM后台数据库1.2 创建数据库用户 DEM1.3 使用DEM用户导入dem_init.sql 2 配置tomcat2.1 配置/tomcat/conf/server.xml2.2 修改jvm启动参数 3 配置JAVA 1.8及以上版本的运行时环境3.1 配置…

【狂神说Java】SpringCloud | Netflix | Eureka | Ribbon | Feign | Zull | config | 详细笔记(全)

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;狂神说Java &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远…

基于连续Hopfield神经网络优化——旅行商问题优化计算

大家好&#xff0c;我是带我去滑雪&#xff01; 利用神经网络解决组合优化问题是神经网络应用的一个重要方面。所谓组合优化问题&#xff0c;就是在给定约束条件下&#xff0c;使目标函数极小&#xff08;或极大&#xff09;的变量组合问题。将Hopfield网络应用于求解组合优化问…

c++四种类型转换

首先我们要先引入上行转换和下行转换的概念 所谓上行转换&#xff0c;即将原来的子类指针转换成父类指针&#xff1b; 下行转换即将原来的父类指针转换成子类指针 由于子类对象的空间较大&#xff0c;所以把子类强制转换父类给父类指针赋值时&#xff0c;父类指针对象能读取…

Android图形系统之X11、Weston、Wayland、Mesa3D、ANGLE、SwiftShader介绍(十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

力扣刷题-二叉树-翻转二叉树

226.翻转二叉树 翻转一棵二叉树。 思路 参考&#xff1a; https://www.programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E6%80%9D%E8%B7%AF 如果要从整个树来看&#xff0c;翻转还真的挺复杂&#xff0c;整个树以中间分割线进行翻转&#xf…

基于springboot+vue健身管理系统

基于springbootvue健身管理系统 摘要 健身管理系统是一款基于Spring Boot和Vue.js的全栈应用&#xff0c;致力于为用户提供全面、个性化的健身管理体验。通过Spring Boot构建的后端&#xff0c;系统提供了强大的RESTful API支持&#xff0c;包括用户管理、健身计划制定和健康数…

深度学习_12_softmax_图片识别优化版代码

因为图片识别很多代码都包装在d2l库里了&#xff0c;直接调用就行了 完整代码&#xff1a; import torch from torch import nn from d2l import torch as d2l"获取训练集&获取检测集" batch_size 256 train_iter, test_iter d2l.load_data_fashion_mnist(ba…

msvcp71.dll,msvcr71.dll丢失的最简单的解决方法

在计算机使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是MSVCR71.dll缺失。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。本文将介绍5个修复MSVCR71.dll缺失的方案&#xff0c;帮助用户解决这一问题。 一、重新安装相关…

2756基于微信小程序的图书商城系统

摘要 本文将详细介绍基于微信小程序的图书商城系统的设计和实现。该系统包括服务器端和客户端两部分&#xff0c;能够满足管理员和普通用户的需求。通过对用户需求和功能的分析&#xff0c;本文将详细阐述系统设计的关键环节&#xff0c;包括数据库设计和界面设计。最后&#…

安全框架SpringSecurity-2(集成thymeleaf集成验证码JWT)

一、SpringSecurity 集成thymeleaf ①&#xff1a;复制并修改工程 复制04_spring_security并重命名为05_spring_security_thymeleaf ②&#xff1a;添加配置和依赖 添加thymeleaf依赖 <dependency><groupId>org.springframework.boot</groupId><artif…

C++--二叉树经典例题

本文&#xff0c;我们主要讲解一些适合用C的数据结构来求解的二叉树问题&#xff0c;其中涉及了二叉树的遍历&#xff0c;栈和队列等数据结构&#xff0c;递归与回溯等知识&#xff0c;希望可以帮助你进一步理解二叉树。 目录​​​​​​​ 1.二叉树的层序遍历 2.二叉树的公…

【STM32 CAN】STM32G47x 单片机FDCAN作为普通CAN外设使用教程

STM32G47x 单片机FDCAN作为普通CAN外设使用教程 控制器局域网总线&#xff08;CAN&#xff0c;Controller Area Network&#xff09;是一种用于实时应用的串行通讯协议总线&#xff0c;它可以使用双绞线来传输信号&#xff0c;是世界上应用最广泛的现场总线之一。CAN协议用于汽…

Swift爬虫程序

以下是一个简单的Swift爬虫程序&#xff0c;用于从前程无忧深圳地区招聘财务、会计的数据爬取数据&#xff1a; import Foundation import SwiftSoup// 创建一个请求对象&#xff0c;指定代理信息 var request URLRequest(url: URL(string: "https://www.51job.com/zh/c…