该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

int twice(void *arg, va_list ap)

{

apply_func *func = va_arg(ap, apply_func *);

int status = func(arg, ap);

if (status >= 0)

status = func(arg, ap);

return status;

}

twice函数接收一个函数func和它的参数(注意func的参数以奇怪的方式传递,第一个参数是twice的第一个参数arg,而其他参数与func本身组成了twice的ap,是不是有更好 的方式呢?欢迎与作者讨论。),并调用func两次。(注意第二次调用先判断了func返回的值,统一起见,我将一般通过返回负数表示停止或错误,返回0表示正确,而其他正数用于表示返回的更多信息。)

好了,现在我们来看一个实际点的例子:

int traverse_vector(void *arg, va_list ap)

{

int status = 0;

void **a = arg;

apply_func *func = va_arg(ap, apply_func *);

while (*a != NULL)

if ((status = func(*a++, ap)) < 0)

break;

return status;

}

函数traverse_vector接受一个vector(注意不是C++中的vector,而是main函数的参数argv那种以NULL结尾的指针数组),及一个遍历函数func,对vector的每个元素都调用func。如果在访问某个元素时func返回了负值,遍历将会停止(回忆前面的约定,负值表示停止)。你会发现这是非常有用的一个函数。

好了,现在我们打算将上面三个函数联系起来,但在那之前,我们需要另外一个函数——apply。体系中的函数使用va_list传递额外参数,va_list不是直接构造的,我们需要一种方法开始整个调用,这个方法就是apply函数(它不属于这个体系):

int apply(apply_func *func, ...)

{

int status;

void *arg;

va_list ap;

va_start(ap, func);

arg = va_arg(ap, void *);

status = func(arg, ap);

va_end(ap);

return status;

}

函数apply接收一个函数指针,这个函数属于我们考虑的函数体系,apply的其他参数是变长的,它们将被收集到va_list ap中。在调用时,apply先从ap中抽取func的第一个参数arg,将它和剩余的参数ap一起传递给func。

c语言变长参数 第一个参数必须吗,一种使用变长参数为C程序构造灵活回调函数的方法...相关推荐

  1. c语言函数可变长参数,一种使用变长参数为C程序构造灵活回调函数的方法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 int twice(void *arg, va_list ap) { apply_func *func = va_arg(ap, apply_func * ...

  2. 变速恒频风电机组的优缺点_两种主流变速恒频风电机组技术发展综述

    两种主流变速恒频风电机组技术发展综述 [摘 要]通过对目前大型风电机组技术研究,分别对双馈异步.永磁同步 直驱两种主流变速恒频机组从典型接线方式, 各种控制技术研究热点等多方面进 行分析比较, 认为新 ...

  3. japidocs怎么设置参数必填_常用的3种拍摄模式,相机参数怎么设置?如何正确曝光?...

    初入摄影不知道什么是曝光三要素,不知道参数到底该怎么调.今天我们就来学习一下怎么才能得到一张曝光正确的照片. 我们先来学习一下曝光三要素.为什么要学习曝光三要素?因为控制曝光的参数主要有光圈.快门.感 ...

  4. java 无名类做参数_说说你知道的几种主要的JVM参数

    思路: 可以说一下堆栈配置相关的,垃圾收集器相关的,还有一下辅助信息相关的. 1)堆栈配置相关 -Xmx3550m: 最大堆大小为3550m. -Xms3550m: 设置初始堆大小为3550m. -X ...

  5. pythontk界面显示函数中的变量值_简单易学,西门子触摸屏3种修改变量值的方法!博图Wincc V14组态...

    应条友要求,今天分享3种修改触摸屏变量值的最常用方法! 全文约700字,通读4分钟! 看完本章,你将收获以下内容: 一:必会知识点:3种修改变量的方法及适用点 二:实例:3种方法修改触摸屏变量值 三: ...

  6. C语言程序设计之回调函数实现方法

    回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定 ...

  7. js 参数为回调函数

    参数为回调函数 数组常用方法(参数为回调函数) foreach map filter every some find reduce 数组常用方法(参数为回调函数) foreach 对数组的每个元素执行 ...

  8. Go语言教程第三集 集合、函数和方法

    04 集合类型:如何正确使用 array.lice 和 map? 上节课的思考题是练习使用 for 循环中的 continue,通过上节课的学习,你已经了解 continue 是跳出本次循环的意思,现 ...

  9. ES mapping 映射参数第一期之~ Analyzer

    前言 本文是ES mapping 映射参数第一期~ Analyzer. 文中使用 ES versions 7.1,其他版本可能有偏差. mapping 映射参数预计是每周3章,有喜欢的欢迎关注,一起交 ...

最新文章

  1. 利用spring aop统一处理异常和打日志
  2. 自研Spring容器,带你解析ioc内部原理
  3. 一句话总结人工神经网络
  4. fastjson json串转list
  5. Cesium界面学习以及隐藏界面控件
  6. nginx缓存和flask_cache
  7. 使用mac m1跑fortran代码hello world
  8. 通过DataWorks数据集成归档日志服务数据至MaxCompute进行离线分析
  9. mybatis的select、insert、update、delete语句
  10. Immutable Collections(3)Immutable List实现原理(中)变化中的不变
  11. 使用宽度优先搜索的常见场景
  12. C 获得程序执行时间
  13. CNDS-Markdown之公式编辑(一)
  14. Keil中如何生成bin文件
  15. 开启阿里云linux下的pure-ftpd被动模式,解决flashfxp可连接但无法下载的问题
  16. visual studio 2017 installer 安装包制作过程出现的问题---无法注册模块 HRESULT -2147024769 请与您的技术支持人员联系...
  17. arduino 步进电机驱动库_arduino中驱动 步进电机
  18. 联想SR158 安装CentOS7系统
  19. ValueError: You are trying to load a weight file containing 0 layers into a model with 16 layers.
  20. Python调用腾讯优图OCR通用API实现文字识别

热门文章

  1. 一键托管,阿里云全链路追踪服务正式商用:成本仅自建1/5或更少
  2. Michael Jordan:当下的AI其实都是伪“AI” 1
  3. 新功能:阿里云负载均衡SLB支持HTTP访问强制跳转HTTPS
  4. 什么是 “原型模式” ?
  5. ESL:我们如何使用首云混合云产品实现提效降本
  6. 10个工程师,9个不合格!!
  7. CPU有个禁区,内核权限也无法进入!
  8. 寻找榜样的力量!CSDN【百万人学 AI】评选活动重磅启动
  9. python字典是什么数据结构_Python常用数据结构——字典
  10. c++ 打印条码_金蝶盘点机PDA仓库条码管理之——外购入库扫码开单操作