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

C++传递不定参函数

定义不定参数函数,要用到下面这些宏:

  • va_start(ap, farg): 初始化一个va_list变量ap,farg是第一个形参
  • va_arg(ap, type): 获取(下)一个type类型的参数
  • va_end(ap): 结束使用ap

C语言里编写不定参数函数的形式是这样的:

#include <stdarg.h>
int sum(int cnt,...) {
    int sum = 0;
    int i;
    va_list ap;
    va_start(ap, cnt);
    for(i = 0; i < cnt; ++i)
        sum += va_arg(ap, int);
    va_end(ap);
    return sum;
}

定义不定参数函数,要用到下面这些宏:

  • va_start(ap, farg): 初始化一个va_list变量ap,farg是第一个形参
  • va_arg(ap, type): 获取(下)一个type类型的参数
  • va_copy(ap): 用于复制参数列表
  • va_end(ap): 结束使用ap
    这些宏定义一般在stdarg.h里。
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)  )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v)  )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))  )
#define va_end(ap) ( ap = (va_list)0 )

注意: 上面这些宏定义会因不同的系统和不同的处理器架构而不同

_INTSIZEOF宏
_INTSIZEOF这个宏的位运算意义比较难理解,乍一看以为是表示多少个int型的长度,其实它运算出来的结果是按照int型对齐后的长度。比如int型为4个字节,_INTSIZEOF(1)、_INTSIZEOF(2)、_INTSIZEOF(3)、_INTSIZEOF(4)的结果都是4,_INTSIZEOF(5)、_INTSIZEOF(6)、_INTSIZEOF(7)、_INTSIZEOF(8)的结果都是8,这正是x86架构CPU下的参数传递方式,32位即4字节对齐。

几个注意事项

  • 不定参数的函数至少要有一个固定的参数,因为要用它来初始化va_list,比如上面代码中sum函数的cnt参数,同时它也表明了传递的参数的个数。

常用方式

不定参数函数最常用来格式化字符串,一个比较常见的场景是我们想输出一些log消息,但又不能直接在控制台输出,需要自己写一个log函数来格式化log消息并输出。这时我们可以用vsprintf函数:

void log(const char *format, ...) {
    char buf[MAX_BUF_SIZE];
    va_list ap;
    va_start(ap, format);
    vsprintf(buf, format, ap);
    OUTPUT(buf);
}

vsprintf函数的前两个参数和sprintf的前两个参数意义相同,只不过后面的不定参换成了va_list类型的参数列表,这正是让我们用来定义自己的格式化函数的。

附:

  • C语言标准库函数大全

转载于:https://www.cnblogs.com/luzhlon/p/7087080.html

相关文章:

  • Android笔记之网络状态推断
  • mysql 5.6.25编译安装详细步骤
  • 手写 jQuery 框架
  • P1120 小木棍 [数据加强版]
  • Oracle 11gR2 List-Range分区实验
  • python操作excel
  • 一行命令搞定node.js升级
  • 仿射梯度
  • Snapchat发布不到2个月的故事搜索功能,又双叒被Instagram抄袭了
  • 中芯国际第三财季净利润1.136亿美元
  • Jmeter常用函数之__CSVRead使用
  • 苹果计划在英国建立新总部 位于巴特西发电站旧址
  • 保监会:大数据改变保险运作模式
  • 分布式光伏渐入理想状态?
  • 提高人民媒介素养,加强网络安全建设
  • __proto__ 和 prototype的关系
  • 77. Combinations
  • cookie和session
  • Lucene解析 - 基本概念
  • python docx文档转html页面
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 浮动相关
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 我的面试准备过程--容器(更新中)
  • 小试R空间处理新库sf
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • puppet连载22:define用法
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • # Java NIO(一)FileChannel
  • #QT(智能家居界面-界面切换)
  • (4)logging(日志模块)
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (二)正点原子I.MX6ULL u-boot移植
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (三)docker:Dockerfile构建容器运行jar包
  • (三)终结任务
  • (十六)一篇文章学会Java的常用API
  • (顺序)容器的好伴侣 --- 容器适配器
  • (转)为C# Windows服务添加安装程序
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • (状压dp)uva 10817 Headmaster's Headache
  • .FileZilla的使用和主动模式被动模式介绍
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • @Autowired注解的实现原理
  • @RunWith注解作用
  • [100天算法】-实现 strStr()(day 52)
  • [autojs]逍遥模拟器和vscode对接
  • [BZOJ3757] 苹果树
  • [C/C++]数据结构 深入挖掘环形链表问题