C语言 宏定义之可变参数
可变参数宏定义
C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏。可变参数宏就像下面这个样子:
#define dbgprint(...) printf(__VA_ARGS__)
缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。当宏的调用展开时,实际的参数就传递给 printf()了。
可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。
用GCC和C99的可变参数宏, 更方便地打印调试信息
#ifdef DEBUG
#define dbgprint(format, ...) \
fprintf(stderr, format, __VA_ARGS__)
#else
#define dbgprint(format, ...)
#endif
在标准C里,你不能省略可变参数,但是你却可以给它传递一个空的参数。例如,下面的宏调用在ISO C里是非法的,因为字符串后面没有逗号:
dbgprint ("A message")
GNU CPP在这种情况下可以让你完全的忽略可变参数。在上面的例子中,编译器仍然会有问题(complain),因为宏展开后,里面的字符串后面会有个多余的逗号。
为了解决这个问题,CPP使用一个特殊的'##'操作。书写格式为:
#define dbgprint(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
这里,如果可变参数被忽略或为空,'##'操作将使预处理器(preprocessor)去除掉它前面的那个逗号。
如果你在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,
它会把这些可变参数放到逗号的后面。象其它的pasted macro参数一样,这些参数不是宏的扩展。
/* C语言 宏定义之可变参数 */ #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MDEBUG #ifdef MDEBUG
#define TEST_LOG(format,...) fprintf(stderr, format, ##__VA_ARGS__)
#else
#define TEST_LOG(format,...)
#endif int test()
{
int num = ;
TEST_LOG("my num is %d .\n", num);
return num;
} int main()
{
test();
printf("--------ok-------\n");
return ;
}
C语言 宏定义之可变参数的更多相关文章
- GNU中宏定义对可变参数的支持(引自百度)
http://zhidao.baidu.com/question/125413478.html 问:#define PDEBUG(fmt,args...) fprintf(stderr,fmt, ## ...
- C函数和宏中的可变参数
一:调用惯例 函数的调用方和被调用方对函数如何调用应该有统一的理解,否则函数就无法正确调用.比如foo(int n, int m),调用方如果认为压栈顺序是m,n,而foo认为压栈顺序是n, m,那么 ...
- c语言宏定义
一. #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时 ...
- 将C语言宏定义数值转换成字符串!
将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...
- C语言宏定义#define用法
#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...
- C 语言宏定义
C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...
- 宏定义(无参宏定义和带参宏定义),C语言宏定义详解
1.宏定义说明 宏定义是比较常用的预处理指令,即使用"标识符"来表示"替换列表"中的内容.标识符称为宏名,在预处理过程中,预处理器会把源程序中所有宏名,替换成宏 ...
- 嵌入式C语言自我修养 12:有一种宏,叫可变参数宏
12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后, ...
- C语言可变参数宏及‘##’在可变参数中的作用
测试代码及解释: #include <stdio.h> #define PRINT(x) printf x #define SECONDPRINT(fmt,arg...) printf(f ...
随机推荐
- linux系统IO操作
本文重点说明下面内容: 什么是标准IO,什么是文件IO? 什么是Direct IO? O_SYNC标识有什么意义? 各个层面的缓存如何同步? 还在page cache中的脏页可以读写吗? IO路径上的 ...
- Introduction to Linux Threads
Introduction to Linux Threads A thread of execution is often regarded as the smallest unit of proces ...
- Java并发编程-JUC-CountDownLatch 倒计数门闩器-等待多线程完成再放行 -一次性使用
如题 (总结要点) CountDownLatch 倒计数门闩器, 让1-n-1个线程等待其他多线程完成工作. (Excel的多个Sheet的解析,最终等待解析完毕后;要实现主线程等待所有线程完成she ...
- JMeter5.1开发Java协议接口脚本【待完成】
JMeter5.1开发Java协议接口脚本
- arrayAppend.php
<?php $t_full_projects = array(); $t_full_projects[] ='a'; $t_full_projects[] ='b'; $t_full_proje ...
- try catch 小结 , node的回调callback里不能捕获异常 , 不能被v8优化(现在能了),
<深入浅出Nodejs>时,在第四章 - 异步编程中作者朴灵曾提到,异步编程的难点之一是异常处理,书中描述"尝试对异步方法进行try/catch操作只能捕获当次事件循环内的异常, ...
- CF1105D-Kilani and the Game-(多向bfs)
http://codeforces.com/problemset/problem/1105/D 题意:有一片矩阵区域,一开始有多个势力比如1,2,3,4....9,从势力1开始轮流向外扩张,地图上为‘ ...
- Modular Production Line (MCMF)
Modular Production Line \[ Time Limit: 1000ms\quad Memory Limit: 65536kB \] 题意 给出 \(N\) 种零件,现在你可以用连续 ...
- springcloud(三)
雪崩效应 一.为什么需要 Hystrix? 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC).为了保证其高可用,单个服务又必须集群部署.由于网络原因或者自身的原因,服 ...
- JS的ES6的基础语法
JS的ES6 1.let let age = 12; (1). 作用: 与var类似, 用于声明一个变量 (2). 特点: 在块作用域内有效 不能重复声明 不会预处理, 不存在提升 (3). 应用: ...