C语言 __VA_ARGS__


零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门

一.__VA_ARGS__简介

__VA_ARGS__ 是一个可变参数的宏,是新的 C99 规范中新增的,目前似乎只有 gcc 支持( VCVC2005 开始支持)。

__VA_ARGS__需要配合 define 使用,总体来说就是将左边宏中 .. 的内容原样抄写在右边 __VA_ARGS__ 所在的位置; 举个例子:

#define myprintf(...) printf( __VA_ARGS__)

示例代码如下:

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 __VA_ARGS__
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/

#include <stdio.h>

#define myprintf(...) printf( __VA_ARGS__)

int main()
{
    myprintf("0123456789\n");
    myprintf("www.codersrc.com\n");
    myprintf("C语言/C++教程-猿说编程\n");
    return 0;
}

/*
0123456789
www.codersrc.com
C语言/C++教程-猿说编程
*/

注意:__VA_ARGS__ 只能是一些不含任何变量的字符串常量。如果 __VA_ARGS__ 含有变量,整个 printf 的输出与变量便不能一一对应,输出会出错。


二.__VA_ARGS__使用

__DATE__    当前日期,一个以 “MMM DD YYYY” 格式表示的字符串常量。

__TIME__    当前时间,一个以 “HH:MM:SS” 格式表示的字符串常量。

__FILE__    这会包含当前文件名,一个字符串常量。

__LINE__    这会包含当前行号,一个十进制常量。

__STDC__    当编译器以 ANSI 标准编译时,则定义为 1;判断该文件是不是标准C程序。

__FUNCTION__ 程序预编译时预编译器将用所在的函数名,返回值是字符串;


1.__VA_ARGS__宏输出字符串常量

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 __VA_ARGS__
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/

#include <stdio.h>

#define LOGFUNC(...) (printf(__VA_ARGS__" - %d - %s/%s\n",__LINE__,__TIME__,__DATE__))


int main()
{
    LOGFUNC("0123456789");
    LOGFUNC("www.codersrc.com");
    LOGFUNC("C语言/C++教程-猿说编程");
    return 0;
}

/*
0123456789 - 9 - 07:52:40/Jul 11 2021
www.codersrc.com - 10 - 07:52:40/Jul 11 2021
C语言/C++教程-猿说编程 - 11 - 07:52:40/Jul 11 2021
*/

缺点:

  1. 只支持字符串,不支持可变参数或者多个参数;__VA_ARGS__ 只能是一些不含任何变量的字符串常量。
  2. 如果 __VA_ARGS__ 含有变量,整个 printf 输出与变量便不能一一对应,输出会出错; 
/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 __VA_ARGS__
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/

#include <stdio.h>

#define LOGFUNC(...) (printf(__VA_ARGS__" - %d - %s/%s\n",__LINE__,__TIME__,__DATE__))


int main()
{
    LOGFUNC("0123456789");//OK

    //错误写法:只支持字符串,不支持可变参数或者多个参数
    LOGFUNC("%d,%d",1,2); //编译报错
    return 0;
}

/*
main.cpp: In function ‘int main()’:
main.cpp: error: expected ‘)’ before string constant
    4 | #define LOGFUNC(...) (printf(__VA_ARGS__" - %d - %s/%s\n",__LINE__,__TIME__,__DATE__))

*/

2.__VA_ARGS__宏输出可变参数

/******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:C语言教程 - C语言 __VA_ARGS__
//@Time:2021/07/10 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/******************************************************************************************/

#include <stdio.h>

#define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__) 


int main()
{
    //输出可变参数
    LOGSTRINGS("0123456789,%d%s",1,"sd"); //OK
    
    //输出字符串常量报错
    //LOGSTRINGS("C语言/C++教程-猿说编程");
	
    /*LOGSTRINGS("C语言/C++教程-猿说编程");报错如下:
	main.cpp: In function ‘int main()’:
main.cpp: error: expected primary-expression before ‘)’ token
    3 | #define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__)
    */
    return 0;
}

/*
0123456789,1sd
*/

三.__VA_ARGS__缺点

1.仅仅只支持字符串常量,不支持可变参数

#define LOGFUNC(...) (printf(__VA_ARGS__))

2.仅仅只支持可变参数,不支持字符串常量

#define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__) 

那么如何才能解决 __VA_ARGS__ 既能支持常规字符串也能支持可变参数问题,我们可以留到下一篇文章通过 ##__VA_ARGS__ 实现!


四.猜你喜欢

  1. C语言 数组下标越界和内存溢出区别
  2. C语言 指针声明和定义
  3. C语言 指针 p++ / p–
  4. C语言 p++/(p)++/(p++)/p++
  5. C语言 使用指针遍历数组
  6. C语言 指针和数组区别
  7. C语言 指针数组和数组指针区别
  8. C语言 空指针 NULL
  9. C语言 void 指针
  10. C语言 野指针
  11. C语言 函数值传递和址传递
  12. C语言 函数缺省参数
  13. C语言 函数不定长参数
  14. C语言 函数指针
  15. C语言 指针函数
  16. C语言 回调函数 callback
  17. C语言 typedef
  18. C语言 define 定义常量
  19. C语言 define 防止头文件重复包含
  20. C语言 #pragma once
  21. C语言 #include <> 与 #include “” 区别
  22. C语言 const 修饰变量
  23. C语言 const 修饰指针
  24. C语言 const 修饰函数
  25. C语言 const 修饰函数参数
  26. C语言 const 和 define 区别
  27. C语言 #运算符
  28. C语言 ##运算符
  29. C语言 __VA_ARGS__

未经允许不得转载:猿说编程 » C语言 __VA_ARGS__
喜欢(1) 打赏

评论抢沙发

不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!!

开始学习

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏