函数指针(Function Pointer)与 typedef int (*FuncPtr)(int, int);typedef与using(更推荐)

C++ 函数指针(Function Pointer)详解

函数指针是指向函数的指针,它可以存储函数地址,并通过该指针调用函数。函数指针在回调函数、策略模式、动态函数调用等场景中非常有用。


1. 什么是函数指针?

函数指针是一个指向函数的指针,它存储的是函数的地址,并允许通过指针调用该函数

📌 语法

返回类型 (*函数指针名)(参数列表);

2. 基本示例

(1)定义和使用函数指针

#include <iostream>// 普通函数
void hello() {std::cout << "Hello, Function Pointer!" << std::endl;
}int main() {void (*funcPtr)();  // ✅ 定义函数指针funcPtr = hello;    // ✅ 让指针指向 `hello` 函数funcPtr();          // ✅ 通过指针调用函数return 0;
}

📌 输出

Hello, Function Pointer!

funcPtr 存储 hello 函数地址,并通过 funcPtr() 调用它。


3. 带参数和返回值的函数指针

#include <iostream>// 带参数和返回值的函数
int add(int a, int b) {return a + b;
}int main() {int (*funcPtr)(int, int);  // ✅ 定义函数指针funcPtr = add;             // ✅ 让指针指向 `add`std::cout << funcPtr(3, 5) << std::endl;  // ✅ 通过指针调用 `add(3, 5)`return 0;
}

📌 输出

8

funcPtr 存储 add() 地址,调用 funcPtr(3, 5) 计算 3 + 5


4. 函数指针作为函数参数

函数指针可以作为回调函数,在函数内部调用:

#include <iostream>// 定义回调函数类型
void process(int a, int b, int (*op)(int, int)) {std::cout << "Result: " << op(a, b) << std::endl;
}// 具体实现
int add(int x, int y) { return x + y; }
int multiply(int x, int y) { return x * y; }int main() {process(3, 5, add);       // ✅ 传递 `add` 函数process(3, 5, multiply);  // ✅ 传递 `multiply` 函数return 0;
}

📌 输出

Result: 8
Result: 15

process(3, 5, add)op 绑定到 add(),支持动态调用!


5. 使用 typedefusing 简化函数指针

函数指针的语法比较复杂,可以使用 typedefusing 来简化。

(1)使用 typedef

typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针类型int subtract(int a, int b) { return a - b; }int main() {FuncPtr ptr = subtract;  // ✅ 使用 `FuncPtr`std::cout << ptr(10, 3) << std::endl;
}

(2)使用 using(C++11)

using FuncPtr = int (*)(int, int);  // ✅ 定义函数指针类型(C++11)int subtract(int a, int b) { return a - b; }int main() {FuncPtr ptr = subtract;  // ✅ 使用 `FuncPtr`std::cout << ptr(10, 3) << std::endl;
}

typedefusing 让代码更简洁!


6. 函数指针数组

函数指针可以组成数组,实现动态选择函数

#include <iostream>int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }int main() {int (*operations[3])(int, int) = { add, subtract, multiply };  // ✅ 函数指针数组std::cout << operations[0](3, 4) << std::endl;  // 3 + 4 = 7std::cout << operations[1](7, 2) << std::endl;  // 7 - 2 = 5std::cout << operations[2](3, 3) << std::endl;  // 3 * 3 = 9
}

📌 输出

7
5
9

使用索引动态调用不同函数,提高灵活性!


7. C++11 std::function(更现代的方式)

C++11 提供了 std::function 作为函数指针的现代替代,它支持Lambda 表达式、成员函数、绑定参数等

#include <iostream>
#include <functional>  // ✅ 引入 `std::function`int add(int a, int b) { return a + b; }int main() {std::function<int(int, int)> func = add;  // ✅ 绑定普通函数std::cout << func(3, 5) << std::endl;     // ✅ 运行
}

std::function 允许存储更复杂的调用目标,如 Lambda 和成员函数!


8. 结论

功能函数指针**std::function(C++11+)
存储普通函数✅ 支持✅ 支持
存储 Lambda❌ 不支持✅ 支持
存储成员函数❌ 复杂✅ 方便
类型安全❌ 可能出错✅ 更安全
适用场景轻量级回调泛型函数封装

🚀 推荐:C++11 及以上,使用 std::function 代替传统函数指针! 🚀

是的,typedef 在 C++ 中的作用是 给已有类型取别名,但在函数指针的场景中,它可以让复杂的函数指针声明变得更易读和使用。


1. 为什么 typedef 可以用于函数指针?

函数指针的标准声明可能会很复杂,例如:

int (*funcPtr)(int, int);

这意味着 funcPtr一个指针,指向一个接受两个 int 参数并返回 int 的函数

如果我们要在多个地方使用这个函数指针类型,每次都要写 int (*)(int, int),这既冗长又容易出错。使用 typedef 让它更清晰

typedef int (*FuncPtr)(int, int);

这表示:

  • FuncPtr 是一个新的类型别名,它等价于 int (*)(int, int)
  • 现在,我们可以直接使用 FuncPtr 来定义函数指针:
    FuncPtr ptr;  // 等价于 int (*ptr)(int, int);
    

2. typedef 在函数指针中的使用

✅ 使用 typedef 简化函数指针

#include <iostream>typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针类型别名int add(int a, int b) { return a + b; }int main() {FuncPtr ptr = add;  // ✅ `ptr` 现在是一个函数指针std::cout << ptr(3, 5) << std::endl;  // ✅ 调用 `add(3, 5)`
}

📌 输出

8

FuncPtrptr 变得易读,等价于 int (*ptr)(int, int);


3. typedef 用于函数指针数组

函数指针数组允许存储多个函数,并动态选择不同的函数执行:

typedef int (*FuncPtr)(int, int);  // ✅ 定义函数指针别名int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }int main() {FuncPtr operations[] = { add, subtract };  // ✅ 函数指针数组std::cout << operations[0](5, 3) << std::endl;  // ✅ add(5, 3)std::cout << operations[1](5, 3) << std::endl;  // ✅ subtract(5, 3)
}

📌 输出

8
2

operations[0] 选择 add()operations[1] 选择 subtract()


4. C++11 using 替代 typedef

C++11 提供了 using 作为 typedef更现代的替代

using FuncPtr = int (*)(int, int);  // ✅ C++11 写法

typedef 等价,但语法更直观:

FuncPtr ptr = add;

🚀 推荐使用 using,可读性更强!


5. 结论

功能typedef 方式using 方式(C++11)
定义函数指针别名typedef int (*FuncPtr)(int, int);using FuncPtr = int (*)(int, int);
定义函数指针数组FuncPtr arr[2];FuncPtr arr[2];
可读性⭐⭐⭐⭐⭐⭐⭐(更直观)
推荐度✅ 传统 C++ 适用✅ 现代 C++ 推荐

typedef 可以给复杂类型(如函数指针)取别名,提升可读性,但在 C++11 及以上,推荐使用 using 替代 typedef! 🚀

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue笔记(八)

一、Pinia &#xff08;一&#xff09;手动添加Piaia到Vue项目 1.安装Pinia&#xff1a;使用包管理器进行安装&#xff0c;在项目目录下运行 npm install pinia 或 yarn add pinia &#xff0c;为项目引入Pinia状态管理库。 2.创建Pinia实例&#xff1a;在项目的JavaScript代…

vue纯静态实现 视频转GIF 功能(附源码)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、实现后的效果二、使用步骤1.引入库2.下载or复制出来js3. 前端实现 总结 前言 一天一个小demo 今天来一个vue纯静态实现 视频转GIF 功能 上一篇我们讲到了…

嵌入式八股文面试题(二)C语言算法

相关概念请查看文章&#xff1a;C语言概念。 1. 如何实现一个简单的内存池&#xff1f; 简单实现&#xff1a; #include <stdio.h> #include <stdlib.h>//内存块 typedef struct MemoryBlock {void *data; // 内存块起始地址struct MemoryBlock *next; // 下一个内…

【Python】集合

个人主页&#xff1a;GUIQU. 归属专栏&#xff1a;Python 文章目录 1. 集合的创建2. 集合的基本操作2.1 访问集合元素2.2 添加元素2.3 删除元素 3. 集合的数学运算3.1 交集&#xff08;& 或 intersection() 方法&#xff09;3.2 并集&#xff08;| 或 union() 方法&#xf…

Flutter_学习记录_基本组件的使用记录_2

1. PopupMenuButton的使用 代码案例&#xff1a; import package:flutter/material.dart;// ----PopupMemuButtonDemo的案例---- class PopupMemuButtonDemo extends StatefulWidget {const PopupMemuButtonDemo({super.key});overrideState<PopupMemuButtonDemo> crea…

基于java手机销售网站设计和实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

初识计算机网络

从此篇我将开始网络新篇章&#xff01; 1. 网络发展史 最初的计算机之间相互独立存在&#xff0c;每个计算机只能持有自己的数据&#xff0c;数据无法共享。此时的计算机为独立模式 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#x…

PyTorch 中 `torch.cuda.amp` 相关警告的解决方法

在最近的写代码过程中&#xff0c;遇到了两个与 PyTorch 的混合精度训练相关的警告信息。这里随手记录一下。 警告内容 警告 1: torch.cuda.amp.autocast FutureWarning: torch.cuda.amp.autocast(args...) is deprecated. Please use torch.amp.autocast(cuda, args...) i…

【PS 2022】Adobe Genuine Service Alert 弹出

电脑总是弹出Adobe Genuine Service Alert弹窗 1. 不关掉弹窗并打开任务管理器&#xff0c;找到Adobe Genuine Service Alert&#xff0c;并右键进入文件所在位置 2 在任务管理器中结束进程并将文件夹中的 .exe 文件都使用空文档替换掉 3. 打开PS不弹出弹窗&#xff0c;解决&a…

Vue2生命周期面试题

在 Vue 2 中&#xff0c;this.$el 和 this.$data 都是 Vue 实例的属性&#xff0c;代表不同的内容。 1. this.$el this.$el 是 Vue 实例的根 DOM 元素&#xff0c;它指向 Vue 实例所控制的根节点元素。在 Vue 中&#xff0c;el 是在 Vue 实例创建时&#xff0c;指定的根元素&…

unity 安装Entities

因为Entities目前不支持用资源名动态加载资源&#xff01;没错&#xff0c;AssetsBundle或Addressables都不能用于Entities&#xff1b;也就意味着现阶段不能用Entities开发DLC或热更游戏。 Entities必须使用SubScene&#xff0c;而SubScene不能从资源动态加载&#xff0c;路被…

基于 PyTorch 的树叶分类任务:从数据准备到模型训练与测试

基于 PyTorch 的树叶分类任务&#xff1a;从数据准备到模型训练与测试 1. 引言 在计算机视觉领域&#xff0c;图像分类是一个经典的任务。本文将详细介绍如何使用 PyTorch 实现一个树叶分类任务。我们将从数据准备开始&#xff0c;逐步构建模型、训练模型&#xff0c;并在测试…

团结引擎 Shader Graph:解锁图形创作新高度

Shader Graph 始终致力于为开发者提供直观且高效的着色器构建工具&#xff0c;持续推动图形渲染创作的创新与便捷。在团结引擎1.4.0中&#xff0c;Shader Graph 迎来了重大更新&#xff0c;新增多项强大功能并优化操作体验&#xff0c;助力开发者更轻松地实现高质量的渲染效果与…

C# OpenCV机器视觉:模仿Halcon各向异性扩散滤波

在一个充满创意与挑战的图像处理工作室里&#xff0c;阿强是一位热情的图像魔法师。他总是在追求更加出色的图像效果&#xff0c;然而&#xff0c;传统的图像处理方法有时候并不能满足他的需求。 有一天&#xff0c;阿强听说了 Halcon 中的各向异性扩散滤波功能&#xff0c;它…

超详细的数据结构3(初阶C语言版)栈和队列。

文章目录 栈和队列1.栈1.1 概念与结构1.2 栈的实现 2. 队列2.1 概念与结构2.2 队列的实现 总结 栈和队列 1.栈 1.1 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进行插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另…

利用邮件合并将Excel的信息转为Word(单个测试用例转Word)

利用邮件合并将Excel的信息转为Word 效果一览效果前效果后 场景及问题解决方案 一、准备工作准备Excel数据源准备Word模板 二、邮件合并操作步骤连接Excel数据源插入合并域预览并生成合并文档 效果一览 效果前 效果后 场景及问题 在执行项目时的验收阶段&#xff0c;对于测试…

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码及效果展示

一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例&#xff0c;使用Arduino语言&#xff1a; 硬件连接 INMP441 VCC → ESP32的3.3VINMP441 GND → ESP32的GNDINMP441 SCK → ESP32的GPIO 17INMP441 WS → ESP32的GPIO 18INMP441 SD → ESP32的GPIO 16RG…

用户认证综合实验

实验需求 需求一&#xff1a;根据下表&#xff0c;完成相关配置 需求二&#xff1a;配置DHCP协议&#xff0c;具体要求如下 需求三&#xff1a;防火墙安全区域配置 需求四&#xff1a;防火墙地址组信息 需求五&#xff1a;管理员 为 FW 配置一个配置管理员。要求管理员可以通…

Curser2_解除机器码限制

# Curser1_无限白嫖试用次数 文末有所需工具下载地址 Cursor Device ID Changer 一个用于修改 Cursor 编辑器设备 ID 的跨平台工具集。当遇到设备 ID 锁定问题时&#xff0c;可用于重置设备标识。 功能特性 ✨ 支持 Windows 和 macOS 系统&#x1f504; 自动生成符合格式的…

linux部署node服务

1、安装nvm管理node版本 # 下载、解压到指定目录 wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.39.1.tar.gz tar -zxvf nvm-0.39.0.tar.gz -C /opt/nvm # 配置环境 vim ~/.bashrc~&#xff1a;这是一个路径简写符号&#xff0c;代表当前用户的主目录。在大多数 …