说到这里,有必要提一下“##”连接符号的用法,“##”的作用是对token进行连接,上例中format,args,__VA_ARGS都可以看作是token,如果token为空,“##”则不进行连接,所以允许省略可变参数。对上述2个示例的改造: #defineLOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__)#defineLOG(format, args....
#define LOG(...) printf("log-->%s\n",#__VA_ARGS__) LOG("hello,world");//打印出 log-->"hello,world" LOG(123);//打印出 log-->123 //例子2 #define LOG(...) printf("log-->%s\n",#__VA_ARGS__) 调用:LOG("hello,world"); 调用:LOG(123); #define LOG2(TAG, ...) pri...
c宏定义#define、#、##、__VA_ARGS__符号的理解 #define宏定义就是预处理时字符串替换的过程,不涉及内存分配,效率比较高,所以简单的表达式有些人就喜欢使用宏定义实现 注意:宏定义只是替换操作,不进行任何逻辑运算操作,所以不涉及内存分配 //例子1#defineM 5//将M替换为5printf("结果 = %d\n", M)//编译...
最近在学习如何在海思3531D板子上实现串口通信的时候发现了一个有趣的东西。 在网络上下载的示例代码中,我发现了一行比较陌生的宏定义代码,是在原来的学习中没有使用过的,代码如下: #definedebugpri(mesg, args...) fprintf(stderr,"[HI Serial print:%s:%d:] "mesg"\n", __FILE__, __LINE__, ##ar...
1, #define #define命令定义一个宏: #define MACRO_NAME(args) tokens(opt) 之后出现的MACRO_NAME将被替代为所定义的标记(tokens). 宏可带参数, 而后面的标记也是可选的. 对象宏 不带参数的宏被称为"对象宏(objectlike macro)" #define经常用来定义常量, 此时的宏名称一般为大写的字符串. 这样利于修改这些...
2.4 变参宏:...和__VA_ARGS__通过把宏参数列表中最后的参数写成省略号(...)来实现宏参数可变,而__VA_ARGS__则出现在替换部分中,表明省略号代表什么,如:结果为:注意:省略号只能代替最后的宏参数,像下面这样就是不行的 3. undef指令 #undef指令用于”取消“已定义的#define指令。假如有如下定义:...
count)(marco, ##__VA_ARGS__)#define FOR_EACH_3(marco, arg, ...)marco(3, arg); FOR_EA...
在C 语言中,可以采用命令 #define 来定义宏。该命令允许把一个名称指定成任何所需的文本,例如一个常量值或者一条语句。在定义了宏之后,无论宏名称出现在源代码的何处,预处理器都会把它用定义时指定的文本替换掉。 关于宏的一个常见应用就是,用它定义数值常量的名称: ...
现在再定义一个带可变参数的宏,这样一来,调用者就不必知道结构体 f_args 的结构了: #define f(...) var_f((f_args){__VA_ARGS__}) 现在我们就在C语言中实现了带“默认参数”的方法,全部C语言代码如下,请看: 全部C语言代码 上述C语言代码在 main() 函数中调用 f() 函数,并分别传递了不同的参数,...
moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );\ FILE* fd = fopen(DEBUG_FILE, "a");\ if ( fd != NULL ) {\ fwrite( buffer, strlen(buffer), 1, fd );\ fflush( fd );\ fclose( fd );\ }\ } #else //将调试信息输出到终端 #define printDebugMsg(moduleName, format, ...