函数中的可变参数
发布日期: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秒