函数中的可变参数
发布日期:2021-07-01 04:24:25
浏览次数:2
分类:技术文章
本文共 2364 字,大约阅读时间需要 7 分钟。
文章目录
1 可变参数的使用
1.1 可变参数的要点
C语言中可以定义参数可变的函数。
参数可变函数的实现依赖于stdarg.h头文件:va_list
:参数集合va_arg
:取具体参数值va_start
:标识参数访问的开始va_end
:标识参数访问的结束
可变参数的限制:
- 可变参数必须从头到尾按照顺序逐个访问,无法直接访问中间的参数值。
- 参数列表中至少要存在一个确定的命名参数。
- 可变参数函数无法确定实际存在的参数的数量。
- 可变参数函数无法确定参数的实际类型。
注意:va_arg中如果指定了错误的类型,那么结果是不可预测的。
1.2 可变参数的应用
编写函数计算平均值:
#include#include float average(int n, ...){ va_list args; int i = 0; float sum = 0; va_start(args, n); for(i=0; i
2 可变参数原理分析
2.1 可变参数中设计的各个宏
知道了参数是如传递的及入栈顺序,分析如下代码就很简单了。原理性的实现代码如下:
typedef char * va_list;#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) // 这里是进行内存对齐,32位的实现,如果是64位则不是这种实现#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )//#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )#define va_arg(ap,t) ( *(t *)( ap=ap + _INTSIZEOF(t), ap- _INTSIZEOF(t)) )#define va_end(ap) ( ap = (va_list)0 )
3 宏中如何传递可变参
在c99语法中支持可变参,如下:
void EM_LOG(int level, const char* function, int line, const char* fmt, ...);#define EMLOG(level, fmt...) EM_LOG(level, __FUNCTION__, __LINE__, fmt)
4 可变参的应用:简易log实现
实现较简单,不多说,直接看代码:
log.h:
#ifndef _LOG_H#define _LOG_H#include#include #include #include typedef enum{ LOG_DEBUG = 1, LOG_INFO, LOG_WARNING, LOG_ERROR}LOG_LEVEL_E;#define OPEN_LOG 1#define LOG_LEVEL LOG_DEBUGvoid EM_LOG(int level, const char* function, int line, const char* fmt, ...);#define EMLOG(level, fmt...) EM_LOG(level, __FUNCTION__, __LINE__, fmt)#endif
log.cpp:
#include "log.h"const char* EM_LOGLevelGet(int level){ if (level == LOG_DEBUG) { return "DEBUG"; } else if (level == LOG_INFO) { return "INFO"; } else if (level == LOG_WARNING) { return "WARNING"; } else if (level == LOG_ERROR) { return "ERROR"; } return "UNKOWN";}void EM_LOG(int level, const char* function, int line, const char* fmt, ...){ va_list arg; int len = 0; va_start(arg, fmt); len = vsnprintf(NULL, 0, fmt, arg) + 1; char* buf = (char*)malloc(len); memset(buf, 0, len); vsnprintf(buf, len, fmt, arg);#ifdef OPEN_LOG printf("[%s] [%s : %d] %s\n", EM_LOGLevelGet(level), function, line, buf);#endif va_end(arg);}
main.c:
#include "log.h"int main(void){ EMLOG(LOG_DEBUG, "debug..."); EMLOG(LOG_INFO, "info..."); EMLOG(LOG_WARNING, "warning..."); EMLOG(LOG_ERROR, "error..."); return 0;}
转载地址:https://muzimin.blog.csdn.net/article/details/104027054 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月21日 18时07分02秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
struts返回xml数据例子
2021-07-04
内存对齐详解
2021-07-04
秋招总结(一)-C++归纳
2021-07-04
秋招总结(三)-操作系统归纳
2021-07-04
带缓冲I/O 和不带缓冲I/O的区别与联系
2021-07-04
LINUX CP命令详解
2021-07-04
source insight快捷键及使用技巧
2021-07-04
映 射 ALT 键
2021-07-04
vim使用快捷键F4生成文件头注释、F5生成main函数模板、F6生成.h文件框架模板
2021-07-04
OV5620的视频驱动
2021-07-04
C++中两个类交叉定义或递归定义的解决办法
2021-07-04
记一次Hive 行转列 引起的GC overhead limit exceeded
2019-05-01
OpenGL ES八 - 交叉存取顶点数据
2019-05-01
crontab定时任务写法
2019-05-01
nginx: [emerg] unknown directive "if($remote_addr" in /usr/local/tools/nginx/conf/nginx.conf:57
2019-05-01
module pip has no attribute main问题解决
2019-05-01
LeetCode 134.Gas Station (加油站)
2019-05-01
Python之命名元组 (namedtuple)
2019-05-01
使用libpcap过滤arp
2019-05-01