前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【c语法】##__VA_ARGS__与__VA_ARGS__

【c语法】##__VA_ARGS__与__VA_ARGS__

作者头像
用户11173787
发布2024-08-29 08:02:46
980
发布2024-08-29 08:02:46
举报
文章被收录于专栏:破晓

引言

在调试过程中,我们经常会自定义打印,比如日志信息的输出,这时就会用VA_ARGS,接下来详细讲解!

VA_ARGS

__VA_ARGS__是C语言设定的一个预定义宏,用于处理可变参数的参数列表。通常用在宏定义中,以便宏可以接收不定数量的参数,并将他们作为整体处理。 通常的函数参数列表都是固定的,但也存在着不定参数数量的函数,如:printf ,为了定义可以处理不同参数个数的宏,C99标准引入了 VA_ARGS,下列的代码均在C99及C99以上标准的环境下运行。

__VA_ARGS__表示所有在宏调用中传递的额外参数。它可以放在宏定义的参数列表的末尾,用于接收任意数量的额外参数,比如:

代码语言:javascript
复制
#define LOG_DEBUG(format,...) printf(format,__VA_ARGS__)

解析:

  • DEBUG_LOG 是一个宏,接受至少一个参数 fmt(格式化字符串),后面可以是任意数量的参数。
  • VA_ARGS 表示可变参数列表,在宏展开时会被替换为传递给 DEBUG_LOG 宏的所有实际参数。 示例:
代码语言:javascript
复制
#define LOG_(format,...) printf("[%s:%d]"format"\n",__FILE__,__LINE__,__VA_ARGS__);

如上的代码就是对日志定义的一个宏。


##VA_ARGS

大家在了解__VA_ARGS__时,一定会看到有些地方在该宏定义前使用 ## 运算符来处理可变参数,如:

代码语言:javascript
复制
#define DEBUG_LOG(fmt, ...) \
    printf("[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)

##__VA_ARGS__前面加上##的作用是:当可变参数的个数为0时,这里的##可以把把前面多余的","去掉,否则会编译出错。 当想要在自定义的调试信息加上时间、行数等信息时,应该怎么做呢?先把正确的用法写在前面:

代码语言:javascript
复制
#include <stdio.h>

#define LOG3(fmt, ...)          printf("<%s:%s>:"fmt"\r\n", __FILE__, __FUNCTION__, ##__VA_ARGS__)
int main(int argc, char** argv)
{
    char *str = "test __VA_ARGS__";
    int num = 10086;
    
    LOG3("this is test __VA_ARGS__");
    LOG3("this is test __VA_ARGS__:%s, %d", str, num);
    LOG3();

    return 0;
}

结果为:

代码语言:javascript
复制
<main.c:main>:this is test __VA_ARGS__
<main.c:main>:this is test __VA_ARGS__:test __VA_ARGS__, 10086
<main.c:main>:

但是如果不加##:可变参数为空时,报错。

代码语言:javascript
复制
#include <stdio.h>

#define LOG2(fmt, ...)          printf("<%s:%s>:"fmt"\r\n", __FILE__, __FUNCTION__, __VA_ARGS__)
int main(int argc, char** argv)
{
    LOG2();//不传参数,编译报错
    LOG2("this is test __VA_ARGS__");//编译报错
    LOG2("this is test __VA_ARGS__:%s, %d", str, num);//正常编译
    return 0;
}

分析:

  • 第6行没有传参数,宏定义LOG2(fmt,…)展开后,__VA_ARGS__是空的,这时printf后面剩余一个,,必然编译失败;
  • 第7行虽然传入了字符串,但是该字符串赋值给了LOG2(fmt,…)的第一个参数fmt,宏展开后,printf后面也剩余一个,,所以编译报错。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • VA_ARGS
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档