当前位置: 首页 > article >正文

函数指针(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! 🚀

相关文章:

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

C 函数指针&#xff08;Function Pointer&#xff09;详解 函数指针是指向函数的指针&#xff0c;它可以存储函数地址&#xff0c;并通过该指针调用函数。函数指针在回调函数、策略模式、动态函数调用等场景中非常有用。 1. 什么是函数指针&#xff1f; 函数指针是一个指向函…...

【AI时代】以聊天框的模式与本地部署DeepSeek交互 (Docker方式-Open WebUI)

一、本地部署DeepSeek 参考地址&#xff1a;(含资源下载) https://blog.csdn.net/Bjxhub/article/details/145536134二、安装Docker https://www.docker.com/ 三、拉取Open WebUI 镜像 docker pull ghcr.io/open-webui/open-webui:main 四、启动并验证 启动: docker run …...

【Elasticsearch】监控与管理:集群监控指标

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

鸿蒙接入支付宝SDK后模拟器无法运行,报错error: install parse native so failed.

鸿蒙项目接入支付宝后&#xff0c;运行提示error: install parse native so failed. 该问题可能由于设备支持的 Abi 类型与 C 工程中的不匹配导致. 官网error: install parse native so failed.错误解决办法 根据官网提示在模块build-profile.json5中添加“x86_64”依然报错 问…...

react redux用法学习

参考资料&#xff1a; https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具&#xff1a;deepseek&#xff0c;通义灵码 第一天 安装相关依赖&#xff1a; 使用redux的中间件&#xff1a; npm i react-redu…...

Maven 在 Eclipse 中的使用指南

Maven 在 Eclipse 中的使用指南 引言 Maven 是一个强大的项目管理和构建自动化工具,它可以帮助开发者更高效地管理项目依赖、构建和测试。Eclipse 作为一款流行的集成开发环境(IDE),与 Maven 的结合使用大大提高了 Java 项目的开发效率。本文将详细介绍如何在 Eclipse 中…...

【Matlab优化算法-第13期】基于多目标优化算法的水库流量调度

一、前言 水库流量优化是水资源管理中的一个重要环节&#xff0c;通过合理调度水库流量&#xff0c;可以有效平衡防洪、发电和水资源利用等多方面的需求。本文将介绍一个水库流量优化模型&#xff0c;包括其约束条件、目标函数以及应用场景。 二、模型概述 水库流量优化模型…...

Redis 集群(Cluster)和基础的操作 部署实操篇

三主三从 集群概念 Redis 的哨兵模式&#xff0c;提高了系统的可用性&#xff0c;但是正在用来存储数据的还是 master 和 slave 节点&#xff0c;所有的数据都需要存储在单个 master 和 salve 节点中。 如果数据量很大&#xff0c;接近超出了 master / slave 所在机器的物理内…...

[2025年最新]2024.3版本idea无法安装插件问题解决

背景 随着大模型的持续发展&#xff0c;特别年前年后deepseek的优异表现&#xff0c;编程过程中&#xff0c;需要解决ai来辅助编程&#xff0c;因此需要安装一些大模型插件 问题描述 在线安装插件的时候会遇到以下问题&#xff1a; 1.数据一直在加载&#xff0c;加载的很满 2.点…...

elasticsearch安装插件analysis-ik分词器(深度研究docker内elasticsearch安装插件的位置)

最近在学习使用elasticsearch&#xff0c;但是在安装插件ik的时候遇到许多问题。 所以在这里开始对elasticsearch做一个深度的研究。 首先提供如下链接&#xff1a; https://github.com/infinilabs/analysis-ik/releases 我们下载elasticsearch-7-17-2的Linux x86_64版本 …...

golang 开启HTTP代理认证

内部网路不能直接访问外网接口&#xff0c;可以通过代理发送HTTP请求。 HTTP代理服务需要进行认证。 package cmdimport ("fmt""io/ioutil""log""net/http""net/url""strings" )// 推送CBC07功能 func main() {l…...

【Unity3D】UGUI的anchoredPosition锚点坐标

本文直接以实战去理解锚点坐标&#xff0c;围绕着将一个UI移动到另一个UI位置的需求进行说明。 &#xff08;anchoredPosition&#xff09;UI锚点坐标&#xff0c;它是UI物体的中心点坐标&#xff0c;以UI物体锚点为中心的坐标系得来&#xff0c;UI锚点坐标受锚点(Anchors Min…...

C++多态性之包含多态(一)—学习记录

一、C的包含多态 面向对象程序设计的四大特点为抽象、封装、继承和多态&#xff0c;其中&#xff0c;多态性可以提高代码的可拓展性和可维护性。 多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对类的成员函数的调用&#xff0c;不同的行为是指不同的实…...

KERL文献阅读分享:知识图谱与预训练语言模型赋能会话推荐系统

标题期刊年份Knowledge Graphs and Pre-trained Language Models enhanced Representation Learning for Conversational Recommender SystemsJournal of LaTeX Class Files2021 &#x1f4c8;研究背景 在数字时代&#xff0c;个性化推荐系统已经成为了我们生活的一部分。从电…...

C#、.Net 中级高级架构管理面试题杂烩

1、简述值类型和引用类型的区别 存储位置&#xff1a;值类型变量直接存储数据的值&#xff0c;通常存储在栈上&#xff1b;引用类型变量存储的是对象在堆上的引用地址。 内存管理&#xff1a;值类型的内存由系统自动管理&#xff0c;当超出作用域时自动释放&#xff1b;引用类…...

从零开始:使用Jenkins实现高效自动化部署

在这篇文章中我们将深入探讨如何通过Jenkins构建高效的自动化部署流水线&#xff0c;帮助团队实现从代码提交到生产环境部署的全流程自动化。无论你是Jenkins新手还是有一定经验的开发者&#xff0c;这篇文章都会为你提供实用的技巧和最佳实践&#xff0c;助你在项目部署中走得…...

Lua限流器的3种写法

学而不思则罔&#xff0c;思而不学则殆 引言 上篇文章讲解了Lua脚本&#xff0c;事务和Pipline之间的使用方式和性能差距&#xff0c;本篇文章将聚焦Lua脚本&#xff0c;我将用三种写法来展现如何实现一个Redis限流器 固定窗口限流 固定窗口限流也是最简单的限流算法&#x…...

hive的几种复杂数据类型

Hive的几种复杂数据类型 Hive 提供了几种复杂数据类型&#xff0c;能够支持更灵活和多样的数据存储。这些复杂数据类型对于处理嵌套数据或不规则数据特别有用。主要包括以下几种&#xff1a; 文章目录 Hive的几种复杂数据类型1. 数组&#xff08;ARRAY&#xff09;2. 结构体&a…...

序列化/反序列化与TCP通信协议

深入理解序列化/反序列化与TCP通信协议 一、序列化与反序列化 1.1 基本概念 序列化&#xff08;Serialization&#xff09;: 将数据结构或对象状态转换为可存储/传输格式的过程反序列化&#xff08;Deserialization&#xff09;: 将序列化后的数据恢复为原始数据结构的过程 …...

Ollama 本地部署 体验 deepseek

下载安装ollama,选择模型 进行部署 # 管理员命令行 执行 ollama run deepseek-r1:70b浏览器访问http://ip:11434/ 返回 Ollama is runninghttp://ip:11434/v1/models 返回当前部署的模型数据 下载安装CherryStudio&#xff0c;本地对话UI 客户端 在设置中 修改API地址&#x…...

Linux探秘坊-------4.进度条小程序

1.缓冲区 #include <stdio.h> int main() {printf("hello bite!");sleep(2);return 0; }执行此代码后&#xff0c;会 先停顿两秒&#xff0c;再打印出hello bite&#xff0c;但是明明打印在sleep前面&#xff0c;为什么会后打印呢&#xff1f; 因为&#xff…...

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…...

树莓派上 基于Opencv 实现人脸检测与人脸识别

一&#xff0c;需求 基于树莓派4b&#xff0c;usb1080p摄像头&#xff0c;实现人脸检测与人脸识别。尝试了海陵科的模组和百度的sdk。海陵科的模组无法录入人脸&#xff0c;浪费了100多块钱。百度的sdk 在树莓派上也无法录入人脸&#xff0c;官方解决不了。最后只能用opencv自…...

vscode怎么更新github代码

vscode怎么更新github代码 打开终端&#xff1a; 在 VS Code 中&#xff0c;使用快捷键 Ctrl (Mac 上是 Cmd) 打开终端。 导航到项目目录&#xff1a; 确保你当前所在的终端目录是你的项目目录。如果不是&#xff0c;可以使用 cd 命令导航到项目目录&#xff0c;例如&#xf…...

Golang Web单体项目目录结构最佳实践

在Golang 开发Web 项目的过程中&#xff0c;如何组织目录结构是一项至关重要的任务。合理的目录结构不仅能提高代码的可维护性&#xff0c;还能为团队协作提供清晰的代码规范。 为什么要设计合理的目录结构&#xff1f; 在 Golang 项目中&#xff0c;代码的组织方式会影响开发…...

Zookeeper 作注册中心 和nacos 和eruka 有什么差异 ?基于什么理论选择?

目录 三者的差异 1. 设计定位与功能特性 2. 服务注册与发现机制 3. 可用性与容错性 4. 性能 选择依据 1. 业务场景 2. 可用性和一致性需求 3. 性能需求 三者的差异 1. 设计定位与功能特性 Zookeeper 设计定位:最初是为分布式应用提供协调服务的,本身并不是专门作为…...

mac下dify+deepseek部署,实现私人知识库

目前deepseek 十分火爆&#xff0c;本地部署实现私有知识库&#xff0c;帮助自己日常工作&#xff0c;上一篇使用工具cherry studio可以做到私人知识库。今天学习了一下&#xff0c;使用Dify链接deepseek&#xff0c;实现私人知识库&#xff0c;也非常不错&#xff0c;这里分享…...

CSS 实现下拉菜单效果实例解析

1. 引言 在 Web 开发过程中&#xff0c;下拉菜单是一种常见且十分实用的交互组件。很多前端教程都提供过简单的下拉菜单示例&#xff0c;本文将以一个简洁的实例为出发点&#xff0c;从 HTML 结构、CSS 样式以及整体交互逻辑三个层面进行详细解析&#xff0c;帮助大家理解纯 C…...

C# 比较两个List集合内容是否相同

在 C# 中&#xff0c;要比较两个 List<T> 集合的内容是否相同&#xff0c;可以通过以下几种方法&#xff1a; 一、非自定义类的元素比较 1. 使用 SequenceEqual 方法&#xff08;顺序和内容都相等&#xff09; 顺序和内容都相等&#xff1a;使用 SequenceEqual。 usin…...

x64、aarch64、arm与RISC-V64:详解四种处理器架构

x64、aarch64、arm与RISC-V64:详解四种处理器架构 x64架构aarch64架构ARM架构RISC-V64架构总结与展望在计算机科学领域,处理器架构是构建计算机系统的基石,它决定了计算机如何执行指令、管理内存和处理数据。x64、aarch64、arm与RISC-V64是当前主流的四种处理器架构,它们在…...