PP_ARG_N(...)会展开为该宏调用中参数的个数,它利用PP_ARG_X宏作为辅助,PP_ARG_X有M+2个固定参数,再加一个可变参数列表,其展开为固定参数列表的最后一个参数 XX。 当通过PP_ARG_N给PP_ARG_X传递的变参列表__VA_ARGS__代表的参数列表长度为 N 时,PP_ARG_X的参数 XX 将展开为 N,于是我们就得...
使用GCC的变参宏(Varadic Macros)扩展实现: 1/*2* main.c3*4* Created on: 2015年1月29日5* Author: lucifet6*/78#include <stdio.h>9#include <stdarg.h>1011#defineAPP_DETAIL 012#defineAPP_MSG 113#defineAPP_WARN 214#defineAPP_ERROR 315#defineAPP_FAIL 416#defineAPP_FATAL 51718#defineTRUE ...
函数内部对可变参数都用va_list及与它相关的三个宏来处理,这是实现变参调用的关键之处。在<stdarg.h>中可以找到va_list的定义:typedef char *va_list;再介绍与它关系密切的三个宏要介绍下:va_start(),va_end()和va_arg()。同样在<stdarg.h>中可以找到这三个宏的定义:#define va_start(ap,v) ( ap...
变参宏的实现形式其实跟变参函数差不多:用… 表示变参列表,变参列表由不确定的参数组成,各个参数之间用逗号隔开。可变参数宏使用 C99 标准新增加的一个VA_ARGS预定义标识符来表示前面的变参列表,而不是像变参函数一样,使用 va_list、va_start、va_end 这些宏去解析变参列表。预处理器在将宏展开时,会用变...
注意:PRINT_XN(n)宏用#运算符组合字符串,##运算符把记号组合成一个新的标识符。 3、变参宏:...和__VA_ARGS__ 一些函数(如printf())接受数量可变的参数。stdvar.h头文件提供了工具,让用户自定义带可变参数的函数。C99/C11也对宏提供了这样的工具。 通过把宏参数列表中最后的参数写成省略号(即,3个点....
变参列表的宏函数 C语言提供了一组宏函数,用来对变参列表进行操作,分别是:va_startva_argva_endva_copy 这四个宏函数对变参裂变进行的相关数据,都保存在C语言标准提供的va_list结构里。这四个宏函数的作用如下:va_start 表示对变参列表开始操作。va_copy 创造变参列表的一份副本。va_arg 表示将要访问...
标识符中的...代表可变参数,args表示可变参数的名字,__LINE__是编译器内置的宏定义,表示当前行号。对于以上宏定义,如果我们传入的可变参数为空,会造成fprintf参数中多了一个逗号从而报错,为了解决这个问题,使用##表示如果可变参数为空,预处理器将去除掉它前面的那个逗号。
运行结果: sum = 6 sum = 30 其实本质上就是用int arg[] = {VA_ARGS}对宏的变参部分构造了一个局部变量数组,便于求出参数的数量。 5月份注册的简书,今天才写第一篇文章啊,转载请注明出处哦^_^
第20行代码用 __VA_ARGS__ 来代表宏定义参数中的三个点(...),也就是可变参数。 再来说说“##”。 如果调用:debug2("code = %d", 100); 这样调用没有问题。 如果调用:debug2("hello"); 这里调用时,在format后面没有传入任何参数,那么就会编译错误,因为在宏替换之后变成了 printf("hello",),第一个...
C语言宏的参数类型有以下几种: 常规参数:可以是任何类型的表达式,包括基本数据类型(例如int、float等)、指针、结构体等。 字符串参数:使用双引号括起来的字符串,例如:“Hello, World!”。 字符参数:使用单引号括起来的字符,例如:‘A’。 变参宏参数:使用省略号(…)表示,可以接受可变数量的参数。在宏的定义...