关于函数指针的一些例子说明

函数指针是什么?

大家都知道,指针的本质,无非就是一个值,用来指向一个内存的地址。
在一个可执行程序中,函数本身也被加载到内存中,并且也有一个具体的地址。
因此,同样可以用指针来指向一个函数,这种指向函数入口地址的指针,就是函数指针

为什么要使用函数指针?

上面说了,函数指针是一种指向函数的指针,它可以存储函数的地址,并在需要时调用该函数。
函数指针在C++中有很多用途,以下是一些常见的应用场景:

  • 回调函数:函数指针最常用的用途之一是实现回调机制。在回调机制中,一个函数接受另一个函数作为参数,并在某个事件或条件满足时调用它。这在事件驱动编程和异步编程中非常有用。
  • 函数数组:可以创建一个函数指针数组,这样就可以根据索引来调用不同的函数。这在实现基于状态机的程序时非常有用,可以根据状态选择不同的行为。
  • 多态:函数指针可以用来实现运行时多态。通过将函数指针指向派生类的成员函数,可以在基类指针上调用派生类中重写的方法。
  • 动态绑定:函数指针可以用来实现动态绑定,即在运行时决定调用哪个函数。这在需要根据不同情况调用不同函数时非常有用。
  • 接口实现:在没有虚函数的类中,函数指针可以用来模拟接口的行为,允许不同的类通过不同的实现来响应相同的操作。
  • 优化代码:在某些情况下,使用函数指针可以提高代码的执行效率,尤其是在需要频繁调用函数的情况下,通过函数指针直接调用可以减少函数查找的时间。
  • 信号和槽机制:在Qt等框架中,函数指针用于实现信号和槽机制,允许对象之间的松耦合通信。
  • 函数工厂:函数指针可以用来创建函数工厂,即根据输入参数动态创建并返回不同类型的函数。
  • 装饰器模式:在设计模式中,函数指针可以用来实现装饰器模式,允许在不修改原有函数的情况下增加额外的功能。
    等等。
    函数指针是C++中一个强大的特性,它提供了一种灵活的方式来引用和调用函数,使得代码更加模块化和可重用。

先来看一个Hello World程序

int main(int argc,char* argv[])
{printf("Hello World!\n");return 0;
}

采用函数调用的形式来实现

这是一种常规的使用方式。

void Invoke(char* s);
int main(int argc,char* argv[])
{Invoke("Hello World!\n");return 0;
}void Invoke(char* s)
{printf(s);
}

用函数指针的方式来实现

如下:

void Invoke(char* s);int main()
{void (*fp)(char* s);    //声明一个函数指针(fp)        fp=Invoke;              //将Invoke函数的入口地址赋值给fpfp("Hello World!\n");   //函数指针fp实现函数调用return 0;
}void Invoke(char* s)
{printf(s);
}

说明

函数指针函数的声明之间唯一区别就是,用指针名(*fp)代替了函数名Invoke,这样这声明了一个函数指针,然后进行赋值语句:

fp=Invoke

就可以进行函数指针的调用了。声明函数指针时,只要函数返回值类型、参数个数、参数类型等保持一致,就可以声明一个函数指针了。
注意,函数指针必须用括号括起来,如下:

void (*fp)(char* s)

函数指针数组

来个例子:

#include <iostream>
#include <string>
using namespace std;typedef void (*FP)(char* s);
void f1(char* s){cout<<s;}
void f2(char* s){cout<<s;}
void f3(char* s){cout<<s;}int main(int argc,char* argv[])
{void* a[]={f1,f2,f3};   //定义了指针数组,这里a是一个普通指针a[0]("Hello World!\n"); //编译错误,指针数组不能用下标的方式来调用函数FP f[]={f1,f2,f3};      //定义一个函数指针的数组,这里的f是一个函数指针f[0]("Hello World!\n"); //正确,函数指针的数组进行下标操作可以进行函数的间接调用return 0;
}

实际中,为了方便,通常用宏定义的方式来声明函数指针,实现程序如下:

typedef void (*FP)(char* s);
void Invoke(char* s);int main(int argc,char* argv[])
{FP fp;      //通常是用宏FP来声明一个函数指针fpfp=Invoke;fp("Hello World!\n");return 0;
}void Invoke(char* s)
{printf(s);
}

后记

c++因为可以直接操作指针,很多时候,可以比java、python、go等高级语言有更多灵活性,所以,在系统层面,还是有其不可替代性的。
关于函数指针的具体应用,慢慢补充。

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

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

相关文章

linux查看系统架构的命令

两种方式&#xff0c;以下以中标麒麟为示例&#xff1a; 1.cat /proc/verison Linux version 3.10.0-862.ns7_4.016.mips64el mips64el即为架构 2.uname -a 输出所有内容 Linux infosec 3.10.0-862.ns7_4.016.mips64el #1 SMP PREEMPT Mon Sep 17 16:06:31 CST 2018 mips64el…

Transformer+KAN系列时间序列预测代码

前段时间&#xff0c;来自 MIT 等机构的研究者提出了一种非常有潜力的替代方法 ——KAN。该方法在准确性和可解释性方面表现优于 MLP。而且&#xff0c;它能以非常少的参数量胜过以更大参数量运行的 MLP。 KAN的发布&#xff0c;引起了AI社区大量的关注与讨论&#xff0c;同时…

分享一个免费的网页转EXE的工具

HTML2EXE是一款在Windows系统下将Web项目或网站打包成EXE执行程序的免费工具。这款工具能够将单页面应用、传统HTMLJavaScriptCSS生成的网站、Web客户端&#xff0c;以及通过现代前端框架&#xff08;如Vue&#xff09;生成的应用转换成独立的EXE程序运行。它支持将任何网站打包…

全新更新!Fastreport.NET 2025.1版本发布,提升报告开发体验

在.NET 2025.1版本中&#xff0c;我们带来了巨大的期待功能&#xff0c;进一步简化了报告模板的开发过程。新功能包括通过添加链接报告页面、异步报告准备、HTML段落旋转、代码文本编辑器中的文本搜索、WebReport图像导出等&#xff0c;大幅提升用户体验。 FastReport .NET 是…

Windows 下实验视频降噪算法 MeshFlow 详细教程

MeshFlow视频降噪算法 Meshflow 视频降噪算法来自于 2017 年电子科技大学一篇高质量论文。 该论文提出了一个新的运动模型MeshFlow&#xff0c;它是一个空间平滑的稀疏运动场 (spatially smooth sparse motion field)&#xff0c;其运动矢量 (motion vectors) 仅在网格顶点 (m…

C++ --- 多线程的使用

目录 一.什么是线程&#xff1f; 线程的特点&#xff1a; 线程的组成&#xff1a; 二.什么是进程&#xff1f; 进程的特点&#xff1a; 进程的组成&#xff1a; 三.线程与进程的关系&#xff1a; 四.C的Thread方法的使用&#xff1a; 1.创建线程&#xff1a; 2.join(…

区块链底层协议比较#DAPP开发

区块链技术在近年来迅速发展&#xff0c;作为一种去中心化的分布式账本技术&#xff0c;区块链在各个领域展现出了巨大的潜力。随着需求的不断增加&#xff0c;各种区块链层级&#xff08;L0、L1、L2&#xff09;应运而生。本文将对这三种层级进行深入的介绍和对比。 一、区块链…

【资调实习报告】华中农业大学资源调查与评价实习报告

一、前言 1.1实验目的与要求 1&#xff09;理论和实践相结合&#xff0c;培养野外独立工作能力&#xff1a;通过将课堂上所学的理论知识与在贺胜桥研究区域的实地调查相结合&#xff0c;帮助学生培养在野外独立工作的能力&#xff0c;包括计划制定、采集数据、观察现象、分析…

《华为工作法》读书摘记

无论做什么事情&#xff0c;首先要明确的就是做事的目标。目标是引导行动的关键&#xff0c;也是证明行动所具备的价值的前提&#xff0c;所以目标管理成了企业与个人管理的重要组成部分。 很多时候&#xff0c;勤奋、努力并不意味着就一定能把工作做好&#xff0c;也并不意味…

异步4位计数器(Quartus与Modelsim联合仿真)

异步计数器&#xff08;也称为ripple-through counter&#xff09;的特点是每一位触发器的输出作为下一位触发器的时钟输入&#xff0c;因此计数速度会因为级联触发器的传播延迟而受到限制。这种计数器的最大工作频率通常低于同步计数器。 一、电路符号 输入信号&#xff1a;时…

TIA 中用 GSD 方式组态 ET200SP 安全模块时如何用 S7-FCT 分配安全目标地址

1 概述 用 GSD 方式组态的 ET200SP 的分布式从站上&#xff0c;现在可以使用安全模块&#xff08;早期 是无法支持&#xff09;&#xff0c;这种用法对 ET200SP 接口模块的版本和编程软件的版本都有要求。 ET200SP 故障安全模块可通过 GSD 文件用于以下接口模块&#xff1a; …

git 入门作业

任务1: 破冰活动&#xff1a;自我介绍任务2: 实践项目&#xff1a;构建个人项目 git使用流程&#xff1a; 1.将本项目直接fork到自己的账号下&#xff0c;这样就可以直接在自己的账号下进行修改和提交。 这里插一条我遇到的问题&#xff0c;在fork的时候没有将那个only camp4的…

C++右值引用

一、右值引用的定义 1、什么是左值和左值引用&#xff1f; 左值指的是可以出现在等号左边&#xff0c;可以被赋值(非const)&#xff0c;可以取地址的值。 左值引用就是左值的引用&#xff0c;给左值取别名。(int& lr a) 2、什么是右值和右值引用&#xff1f; 右值指的是不…

【深度学习】时间序列预测、分类、异常检测、概率预测项目实战案例

说明&#xff1a;本专栏内容来自于个人学习笔记、以及相关项目的实践与总结。写作目的是为了让读者体会深度学习的独特魅力与无限潜力&#xff0c;以及在各行各业之中的应用与实践。因作者时间精力有限&#xff0c;难免有疏漏之处&#xff0c;期待与读者共同进步。 前言 在当今…

【重生之我要苦学C语言】深入理解指针2

深入理解指针2 const修饰指针 当const修饰变量时&#xff0c;是无法更该该变量的值的 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() {const int a 10;//const常属性&#xff0c;不能改变的属性a 1;printf("%d\n", a);return 0; }报错&…

WPF+MVVM案例实战(十八)- 自定义字体图标按钮的封装与实现(ABD类)

文章目录 1、案例效果1、按钮分类2、ABD类按钮实现描述1.文件创建与代码实现2、样式引用与控件封装3、按钮案例演示1、页面实现与文件创建2、运行效果如下3、总结4、源代码获取1、案例效果 1、按钮分类 在WPF开发中,最常见的就是按钮的使用,这里我们总结以下大概的按钮种类,…

ARM base instruction -- mneg

Multiply-Negate multiplies two register values, negates the product, and writes the result to the destination register. 乘法-求反&#xff0c;将两个寄存器值相乘&#xff0c;对乘积求反&#xff0c;并将结果写入目标寄存器。 32-bit variant Applies when sf 0…

【鸿蒙新闻】10月29日警用鸿蒙开发者大会在北京胜利召开,开启智慧应用新时代!

10月29日&#xff0c;在公安部科技信息化局、公安部装备财务局指导下&#xff0c;由公安部第一研究所主办&#xff0c;鼎桥通信技术有限公司、OpenHarmony生态委员会及公共安全专委会协办的警用鸿蒙开发者大会在北京胜利召开。会议以“拥抱警鸿创新生态 开启智慧应用新时代”为…

架构师备考-软件工程相关补充

软件开发生命周期 按照传统的软件生命周期方法学&#xff0c;可以把软件生命周期划分为软件定义、软件开发、软件运行与维护三个阶段。 软件定义&#xff1a;软件定义包括可行性研究和详细需求分析过程&#xff0c;任务是确定软件开发工程必须完成的目标。具体可分为问题定义、…