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

使用typedef封装函数指针新类型

typedef的用法是在定义前加上这个关键字,就能得到一个新的类型名;例如int a;变成typedef int a ;那么就可以用a表示Int了。

比如void (*test)(void);那么加上typedef就变成了typedef void (*test)(void);

类型名test就表示一个返回值是void参数是void的一个函数指针类型,与上面的int a不同这里的变量名是test

void test_opr(void) {};
typedef void (*test)(void);
test ptr = test_opr;
ptr();

void test(void);这个函数声明表示定义了一个参数为void,返回空的test函数。

并且这里面的test的值就是存储函数指针,也就是这个函数的第一条语句的内存地址。

*为解引用操作,对函数进行解引用操作, *test按道理讲要返回函数内容也就是函数体,但是事实上没法返回函数体。就对解引用降级(退化),所以test和*test以及**test不管多少个解引用,结果都是这个函数的内存地址。但还是注意test和*test本质上是不一样的,一个是函数指针存储函数的第一条汇编指令的内存地址,一个是这个函数的函数体,在输出的时候会隐式退化成test。

#include <stdio.h>static int count  = 0;void test(void) {printf("test count %d  task start\n", count++);
}void (*test_por)(void) = test;int main() {printf("test value 0x%X, *test value 0x%X **test value 0x%X &test value 0x%X\n", test, *test, **test, &test);test();(*test)();(**test)();(*test_por)();(&test)();//(&test_por)(); //注意此时这个test_por是存储函数内存地址的容器,也就是说&test_por获取到的是存储函数内存地址的地址所以可以看到后面输出的&test_por地址和test_por不同。也就是说,test_por存储的内存数据,&test_por是存储这个数据的内存地址//事实上,test_por存储的是函数体的第一条指令的地址printf("test_por value 0x%X, *test_por value 0x%X **test_por value 0x%X &test_por value 0x%X\n", test_por, *test_por, **test_por, &test_por);while(1) {}return 0;
}

输出的结果也能证实:

test value 0x681F14A4, *test value 0x681F14A4 **test value 0x681F14A4 &test value 0x681F14A4
test count 0  task start
test count 1  task start
test count 2  task start
test count 3  task start
test count 4  task start
test_por value 0x681F14A4, *test_por value 0x681F14A4 **test_por value 0x681F14A4 &test_por value 0x681F9000
http://www.jsqmd.com/news/909748/

相关文章:

  • 量子计算基础与NISQ时代挑战解析
  • 5种方法彻底解决Windows驱动存储膨胀:DriverStore Explorer实战指南
  • JDK 17 + Hadoop 3.3.5 + Spark 3.3.2 集群搭建避坑全记录:从虚拟机互信到圆周率测试
  • 从‘鸡同鸭讲’到‘无缝对话’:手把手重构一个qiankun微前端的通信层
  • 基于NodeMCU与WS2812B的智能氛围灯DIY:从硬件连接到网页控制
  • 如何永久保存你的微信聊天记忆:WeChatMsg一站式数据管理指南
  • C51项目中代码与数据空间占用的精确计算方法
  • UE4玻璃和水面材质实战:用SurfaceForwardShading和SurfaceTranslucencyVolume打造真实折射反射(附性能对比)
  • 基于Teensy 4.1的离线硬件数据保险库:Serpent-CBC加密实践
  • HARNESS:阿拉伯语专属轻量语音模型的迭代自蒸馏与双语预训练实践
  • Claude用户从新手到高手的7天行为路径图:基于127万条真实交互数据的深度还原
  • 2026年物流园重卡充电桩排名:充电效率、并发补能与平台开放性横向对比 - 科技焦点
  • RK3568+串口mark,space校验设置
  • 从WS2812B到ESP8266:打造智能发光领带的物联网全栈实践
  • K8s持久化存储太贵?试试JuiceFS CSI Driver,成本直降80%的实战配置指南
  • 徐州黄金上门回收实测 福运来黄金回收领跑六强逐鹿谁更省心 - 黄金回收
  • 信道容量迭代算法:从理论公式到代码实现的完整指南
  • 2026年|知网5.0文章AIGC检测爆红?亲测10大降AI软件红黑榜(附去AI痕迹指南) - 降AI实验室
  • 基于Arduino与3D打印的DIY模拟赛车方向盘制作全攻略
  • MATLAB三元相图进阶玩法:用STernary类绘制带等高线、气泡图和凸包的数据可视化
  • 文档获取工具终极指南:如何免费下载百度文库等30+平台资源
  • 基于CircuitPython的交互式旋转木马:从硬件到代码的创客实践
  • 探索VSCode Mermaid插件:用代码重构技术文档可视化工作流
  • 用PyTorch复现f-AnoGAN:一个工业缺陷检测的实战项目(附完整代码与数据集处理)
  • 避坑指南:在Linux服务器上部署Docker版Jitsi Meet时,你可能遇到的5个典型问题及解决
  • 给电赛萌新的保姆级教程:用CubeMX+Keil5从零点亮STM32F407(附避坑指南)
  • 【小白必学】OpenClaw 2.7.5 实用 Skill 技能推荐 办公效率提升指南(包含安装包)
  • Agent 一接浏览器权限弹窗就开始误点允许:从 Permission State 到 Prompt Deferral 的工程实战
  • 告别Putty!用Tabby打造你的现代化SSH终端:从下载安装到SFTP传文件保姆级教程
  • 告别吃灰!用这3款免费软件,把你的旧iPad变成Windows电脑的第二块屏幕