【系列】C/C++函数指针详解-3

C/C++函数指针全解析:从回调机制到设计模式底层实现 在编程中,函数指针是一种将函数作为数据处理的机制,它允许程序在运行时动态选择和执行代码。从原理上看,函数名在编译后对应内存中的地址,函数指针就是存储这些地址的变量,实现了行为的参数化。这一机制的技术价值在于解耦调用方与具体实现,支持回调函数、策略模式等设计思想,广泛应用于事件驱动系统、算法库接口和插件架构中。例如,标准库的qsort通过函数指针实现通用排序,而函数指针数组则常用于命令分发和状态机。本文深入探讨了C风格函数指针、成员函数指针的声明与使用,并对比了现代C++中std::function和lamb 阅读详情

 

3.6 使用函数指针数组

函数指针有意思的地方在于,它使用从0到n-1这个n个连续的整数下标直接映射到函数上。

和前面一样,我们也是类比着定义普通指针数组来定义函数指针数组。首先,考虑一个浮点数指针数组,数组的长度为10.我们都知道用下面的形式来定义:

float * pFloatArray[10];

从形式上分析,用中括号明确了是定义指针变量还是定义指针数组这个语义。用数字10明确了这个数组能容纳多少个函数指针这个语义。形式上看,中括号是紧接在指针名称的后面再中括号里面是一个需要在编译时期间就能够确定的常数。

现在我们来类比函数指针数组的定义,定义一个指向函数指针类型为:float (*)(float,float)的函数指针数组,数组长度为10.正确的形式为:

float(* pFunctionArray[10])(float,float)

从形式上看,这种定义方式和定义普通指针的定义方式是一致的:都是在指针名称后面紧接着一个中括号,然后里面是一个编译期间能够确定的常数。这种形式上的一致性,可以方便我们对形式的记忆,进而达到对内容的理解。

下面是一个例子程序:

/*
*Author:Choas Lee 
*Date:2012-02-28 
*/ 
#include<stdio.h> 
float add(float a,float b){return a+b;} 
float minus(float a,float b){return a-b;} 
float multiply(float a,float b){return a*b;} 
float divide(float a,float b){return a/b;} 
int main() 
{ 
      float(*func_pointers[4])(float,float)={add,minus,multiply,divide}; 
      int i=0; 
      float a=10.0,b=5.0; 
      for(i=0;i<4;i++) 
      { 
             printf("result is %f\n",func_pointers[i](a,b)); 
      } 
      return 0; 
} 

以下为对应的运行结果:

result is 15.000000 
result is 5.000000 
result is 50.000000 
result is 2.000000 

3.7 使用typedef

从哲学角度讲,形式过于复杂的话,还是抽象的层次太低。如果我们使用多层次的抽象,这样最上层的表示就会简化很多。这就是引入typedef的原因,使用typedef可以简化函数指针的定义,因为typedef可以定义新的类型:

同样,在使用typedef定义函数指针类型的时候,也和普通的使用typedef引入新类型的方式不一样。我们和前面一样对照着普通的定义方式来学习:

typedef int bool;

这在C语言中很常用,由于C语言中没有bool类型,这样定义之后可以从形式上引入一个bool类型,提高代码可读性。所以形式为:
           typedef 
已知类型 新类型;

现在我们要将float (*)(float,float)类型声明为一种新类型,按照上面的方式,貌似为:typedef float(*)(float,float) fpType;然而,前面的经验告诉我们应该这样定义啊:

typedef float(*fpType)(float,float);

这样我们就可以用fpType来表示float (*)(float,float)这种类型了。所以定义一个新的指向float (*)(float,float)类型的指针变量的时候,我们就可以采用下面这种形式了:

fpType pFunction;

在定义函数指针数组的时候可以这样定义:

fpType pFunctions[10];

在定义函数指针类型参数时可以这样定义:

void func(fpType pFunction);

在定义函数指针类型的返回值时可以这样定义:

fpType func(int a);

现在我们再来看一下,unix中的那个signal函数,其形式为:

void (*signal)(int signo,void (*func)(int)))(int);

现在我们定义一个类型为:

typedef void (*pSgnType)(int);

这样上面的函数就能表达为:

pSgnType signal(int signo,pSgnType func);

这样是不是看起来清爽多了。

其实上面的signal函数也能这样定义:

首先引入新类型:

typedef void SgnType(int)

然后signal函数的声明改为:

SgnType *signal(int signo,SgnType *func);

按照前面对这些形式的解释,理解这个应该没难度~~

现在在引入最后一个例子,关于使用typedef来简化函数指针定义的:

/* 
*Author:Choas Lee 
*Date:2012-02-29 00:25 
*/ 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
float add(float a,float b){return a+b;} 
float minus(float a,float b){return a-b;} 
float multiply(float a,float b){return a*b;} 
float divide(float a,float b){return a/b;}  
typedef float (*pArithmeticOperations)(float,float); 
typedef float ArithmeticOperations(float,float); 
int main() 
{ 
      pArithmeticOperations pao=add; 
      pArithmeticOperations paos[4]={add,minus,multiply,divide}; 
      ArithmeticOperations *ao=add; 
      ArithmeticOperations *aos[4]={add,minus,multiply,divide}; 
      float a=10.0,b=5.0; 
      float result=0.0; 
      int i=0; 
      result=pao(a,b); 
      printf("the result of pao is %f\n",result); 
      printf("the results of paos are:\n"); 
      for(i=0;i<4;i++) 
      { 
             result=paos[i](a,b); 
             printf("result=%f\n",result); 
      } 
      result=ao(a,b); 
      printf("\n\nthe result of ao is :%f\n",result); 
      printf("the results of aos are:\n"); 
      for(i=0;i<4;i++) 
      { 
             result=aos[i](a,b); 
             printf("result=%f\n",result); 
      } 
      return 0; 
} 

输出结果为: 

result=15.000000 
result=5.000000 
result=50.000000 
result=2.000000 
the result of ao is :15.000000 
the results of aos are: 
result=15.000000 
result=5.000000 
result=50.000000 
result=2.000000

PS:参考《Function pointer tutorial》.

主流几个JDK版本:JDK 8、JDK 11、JDK 17 和 JDK 21 的区别 阅读详情

相关推荐

rv1126 读取sensor输入,输出到屏幕显示【RK_MPI API接口】

rv1126 libdrm VO

学习记录 1万+

C/C++函数指针与回调机制:从基础语法到现代C++实践

函数指针是C/C++中实现高阶编程的核心工具,本质是存储函数入口地址的变量。其工作原理基于内存中函数代码段的地址寻址,通过指针间接调用函数。这一机制的技术价值在于实现了逻辑与数据的解耦,为动态行为选择和运行时多态提供了轻量级解决方案。在应用场景上,函数指针是回调函数、策略模式、事件驱动和表驱动编程的基础,广泛应用于状态机、命令行解释器、算法库定制(如qsort)等系统编程领域。本文深入探讨了函数指针数组的优化技巧和C++成员函数指针的底层原理,并自然延伸到现代C++中std::function与lambda

weixin_34015336的博客 467

Windows Server安装Intel I219-V网卡驱动完整教程

在Windows Server系统上安装Intel I219-V网卡驱动的方法。

小白成长历程 5176

嗯,让我们彻底搞懂C/C++函数指针吧(三)

3.6使用函数指针数组 函数指针有意思的地方在于,它使用从0到n-1这个n个连续的整数下标直接映射到函数上。 和前面一样,我们也是类比着定义普通指针数组来定义函数指针数组。首先,考虑一个浮点数指针数组,数组的长度为10.我们都知道用下面的形式来定义: float * pFloatArray[10]; 从形式上分析,用中括号明确了是定义指针变量还是定义指针数组这...

weixin_33786077的博客 135

System Verilog学习笔记(十九)——覆盖率

覆盖率是用来衡量验证精度和完备性的数据指标。也可以告诉我们在仿真时设计的哪些结构被触发,哪些没被触发。高质量的验证需要满足以下三个条件。

ljy77882333的博客 2143

MacBook 本地化部署 Dify 指南

dify 怎么安装部署 有哪些坑 !

weixin_44542598的博客 1522

C语言回调函数总结

一、预备知识 1、 什么是函数指针 函数指针也是一种指针,只是它指向的不是整型,字符型而是函数。在C中,每个函数在编译后都是存储在内存中,并且每个函数都有一个入口地址,根据这个地址,我们便可以访问并使用这个函数。函数指针就是通过指向这个函数的入口,从而调用这个函数。【我们平时定义的函数名就是函数的地址,也就是函数的入口】 2、 函数指针的使用 2.1、函数指针的定义 ...

u010917150的专栏 422

QGIS编译(跨平台编译)001:Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

QGIS编译;Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

LuckyHanMo的博客 3080

关于函数指针的理解

typedef  void (*pFunction)(void);     这个看上去有点奇怪; 正常第一个整型变量   typedef  int  a;  就是给整型定义一个别名 a  void (*pFunction)(void);   是声明一个函数指针,加上一个typedef 之后   pFunction只不过是类型 void (*)(void) 的一个别名;

masterloong的博客 538

华为OD机试双机位C卷-组装新的数组(Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【组装新的数组】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - 组装新的数组。

qq_45776114的博客 1145

操作系统实验一到实验九合集(哈工大李治军)

操作系统实验一到实验九合集(哈工大李治军) 有详细代码及注释,程序已在本地测试,均能跑通

leoabcd12的博客 5万+

预编译、类型定义、static、extern及函数指针

1、宏定义 // 不带参数的宏定义 #define pai=3.14int main() { int a; int r=6; a=2*pai*r// 编译前会被替换为 3.14 return 0; } // 带参数的宏定义 #define pingfang(a) (a)*(a); int main() { int res = pingfang(5+5); // 编译前会被替换为 in

a72524的博客 672

【数据集】2019年中国1km格网河网密度数据集

中国1km格网河网密度数据集

WW、forever的博客 1343

【十万字+详解C/C++】C/C++目录(持续更新)

本文是C/C++的文章总目录,包括大目录与详细目录

潮.eth的博客,计算机必关注博主 2075

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【系列】C/C++函数指针详解-1

摘要:这篇文章详细介绍C/C++的函数指针,请先看以下几个主题:使用函数指针定义新的类型、使用函数指针作为参数、使用函数指针作为返回值、使用函数指针作为回调函数、使用函数指针数组,使用类的静态函数成员的函数指针、使用类的普通函数成员的指针、定义函数指针数组类型、使用函数指针实现后绑定以及在结构体中定义函数指针。如果您对以上这几个主题都很了解,那么恭喜您,这篇文章不适合您啦~。在一些开源软件中,如Boost, Qt, lam-mpi中我们经常看到函数指针,本文目的是彻底搞定函数指针的语法和语义,至于怎样将函数

相信并热爱着 1044

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【C/C++】指针

本章节包含指针类型的含义,野指针,二级指针,指针数组,数组指针,数组传参,函数指针,函数指针数组,指向函数指针数组的指针等。

m0_74899080的博客 345

C语言中使用函数指针实现回调

写得Java多的同学一般随手写个interface来可以实现回调了。 public interface CallBack { public void onAnwerListenner(String anwer); } public class Response { CallBack callBack = null; // 全局变量 public void an

Ataraxia的专栏 975

c++函数指针总结

一. 定义 函数指针,即指向函数的指针。 声明格式为: 指向函数返回值类型 (*指针名)(参数表) 举个例子: void f1() { printf("f1(); ");} int f2(int i) { printf("f2(%d);",i); return i+1 } int main() { void (*g1)() =f1; // g1 指向 void()类型的函数 in...

weixin_43937759的博客 938

C++面试基础系列-函数指针与指针函数

指针函数:本质是一个函数,其返回值是一个指针。int* fun() { /* 函数体 */ },这里的函数fun就是一个指针函数,它返回一个指向整数的指针。函数指针:是指向函数的指针变量。,这里pf是一个函数指针,它指向一个返回值为整数的函数。

wesigj的博客 1115

C/C++回调方式系列之二class接口回调和lambda程式

在《C/C++回调方式系列之一》中我们总结了函数指针模式回调,这些回调当时比较原始,容易给人一种面向过程的编程的感觉,而且函数指针的格式比较繁琐,可读性相对差一点。本系列二将总结比较推荐的回调使用模式。 一、class接口回调模式 1. 定义接口 C++可以定义virtual纯虚类作为函数接口类, 例如定义 Introducer接口 class Introducer { public:

SweetTool的专栏 4194

C/C++笔试系列--经典C++笔试题解析3

 经典C++笔试题解析3  Sailor_forever sailing_9806@163.com 转载请注明http://blog.youkuaiyun.com/sailor_8318/archive/2008/10/31/3188958.aspx  31、尽量避免类的值传递,用什么方法可以阻止用户的类值传递?只要声明一个私有的拷贝构造函数即可,其不能被编译器调用,因此无法编

Sailor_forever 2791

Cherno C++系列笔记19——P58~P59 函数指针、lambda表达式

文章目录1.P58 函数指针1.1.函数指针的使用举例1.2.函数指针类型的解释1.3.带参数的函数的函数指针1.4.函数指针作为变量进行调用2.P59 1.P58 函数指针 参考:视频 笔记 注意这里讲的函数指针是C语言中的原始的函数指针,现在在C++中几乎没有人使用了。但是仍然会遇到很多别人写的这种类型的代码。 1.1.函数指针的使用举例 函数指针是将一个函数赋值给一个变量的方法。先看下面的代码 #include<iostream> void HelloWorld() { std::co

qq_42731705的博客 738

c++类成员函数指针

提出疑问 首先问大家一句,什么是函数指针? 肯定有的人会这样回答,函数指针?不就是指向函数地址的一个指针吗?或者就是一个存放着一个函数首地址的变量? 当然,那些有点底层基础的肯定会这样说,函数就是一堆连续的机器码,而函数指针,就是存放了这堆连续机器码首地址的变量。 那么大家是不是回答的时候,考虑的地方是不是仅仅局限于 一般的函数????那么成员函数呢??? 为什么得强调成员函数呢?因为成员函数包括了虚函数和非虚函数(这里涉及虚表问题,可以先简单看看列出的虚函数系列,否则接下来问题会有点难以接受。) 虚函数

寻梦&之璐 8119

C 语言指针高阶详解(三):字符指针 / 数组指针 / 函数指针通关指南

本文深入讲解C语言指针的高阶应用,重点剖析字符指针、数组指针、函数指针及函数指针数组等核心概念。内容涵盖:字符指针的两种用法及常量字符串存储特性;数组指针与指针数组的区分;二维数组传参的本质是传递一维数组地址;函数指针的定义与调用方法;以及函数指针数组实现转移表的应用场景。通过典型示例和笔试题解析,帮助读者掌握指针的进阶用法,为理解回调函数等高级主题打下基础。文章强调指针在C语言中的关键地位,是面试和实际开发的重要知识点。

hwtwhy的博客 791

C/C++回调方式系列之一 函数指针和函数回调模式

一、函数指针 1. 函数的定义 return_type function_name(parameter list) { function_body } return_type: 返回值,函数一定有返回值,返回值为用return关键字。如果void类型返回值,则直接调用return即可; function_name: 函数名称

SweetTool的专栏 3731

C++中指针函数与函数指针的用法

最近有很多同学在面试中被问到了JVM原理相关的面试题,因此小编就想写一个JVM原理相关的一系列文章,希望能帮到大家,拿到高薪offer。 首先,前几篇文章小编准备先写一写关于C/C++的一些知识,因为你要是想研究JVM的原理,必看JVM的源码,看JVM源码,就必须要懂一些C/C++知识,因为JVM就是用C/C++进行编写的。 今天我们就一起来了解一下JVM框架中使用较多且易混淆的两个概念,“指针函数”和“函数指针”,它们是实现C语言动态扩展能力的关键技术之一,如Java中的反射与类动态加载技术,就是通过.

weixin_37152234的博客 645
上一篇: 【系列】C/C++函数指针详解-2
下一篇: VC6.0下配置opengl
下木
博客等级 码龄16年 88粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值