宏定义的使用与注意事项

##是一个连接符号,用于把参数连在一起

#是“字符串化”的意思。出现在宏定义中的#是把跟在后面的参数转换成一个字符串
#define paster( n ) printf( "token " #n" = %d\n ", token##n ) 
所以paster(9);就是相当于 printf("token 9 = %d\n",token9);

可变参数宏(...和_ _VA_ARGS_ _)

__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所代表的字符串。比如:
#define PR(...) printf(__VA_ARGS__)
int main()
{
    int wt=1,sp=2;
    PR("hello\n");
    PR("weight = %d, shipping = %d",wt,sp);
    return 0;
}
输出结果:
hello
weight = 1, shipping = 2
省略号只能代替最后面的宏参数。
#define W(x,...,y)错误!

__attribute__((format(printf, a, b)))

使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。format属性告诉编译器,按照printf, scanf等标准C函数参数格式规则对该函数的参数进行检查。

format的语法格式为:

  • format (archetype, string-index, first-to-check)
  其中,“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。
具体的使用如下所示:
  • __attribute__((format(printf, a, b)))
  • __attribute__((format(scanf, a, b)))
  其中参数m与n的含义为:
    a:第几个参数为格式化字符串(format string);
    b:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几。
其中myprint为自己定义的一个带有可变参数的函数,其功能类似于printf:
//m=1;n=2
extern void myprint(const char *format,...) __attribute__((format(printf,1,2)));
//m=2;n=3
extern void myprint(int l,const char *format,...) __attribute__((format(printf,2,3)));
[NextPage]
需要特别注意的是,如果myprint是一个函数的成员函数,那么m和n的值可有点“悬乎”了,例如:
//m=3;n=4
extern void myprint(int l,const char *format,...) __attribute__((format(printf,3,4)));
其原因是,类成员函数的第一个参数实际上一个“隐身”的“this”指针。
 
do{OTHER_FOO(x)} while(0)的意义:
#define FOO(x) do{OTHER_FOO(x)} while(0)
使用:FOO(x);
1. 增加代码的适应性
2.增加代码的扩展性
主要是宏定义中还可以引用其他宏

字符串化#、拼接字符##和可变参数宏(...和_ _VA_ARGS_ _)的更多相关文章

  1. 嵌入式C语言自我修养 12:有一种宏,叫可变参数宏

    12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后, ...

  2. c语言中的# ## 可变参数宏 ...和_ _VA_ARGS_ _

    1.#假如希望在字符串中包含宏参数,ANSI C允许这样作,在类函数宏的替换部分,#符号用作一个预处理运算符,它可以把语言符号转化程字符串.例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字 ...

  3. 可变参数宏__VA_ARGS__和...

    __VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...

  4. 可变参数宏__VA_ARGS__

    在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...

  5. [转载]用可变参数宏(variadic macros)传递可变参数表

    注意:_VA_ARGS__ 从VS2005才开始支持 在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如: #define pr_debug(fmt,arg...) printk(KER ...

  6. 可变参数宏...和__VA_ARGS__

    __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).实现思想就是宏定义中参数列表的最后一个参数为 ...

  7. CCS5 编译器手动设置dsp支持可变参数宏等问题

    IDE:CSS5.4,compiler不支持可变参数宏.需要手动设置编译器相关选项: Language Option->Language Mode —>no strict ANSI. 1. ...

  8. GNU C和C99标准中的可变参数宏(variadic macros)

    用可变参数宏(variadic macros)传递可变参数表你可能很熟悉在函数中使用可变参数表,如: void printf(const char* format, …); 直到最近,可变参数表还是只 ...

  9. 宏定义中的##操作符和... and _ _VA_ARGS_ _

    1.Preprocessor Glue: The ## Operator 预处理连接符:##操作符 Like the # operator, the ## operator can be used i ...

随机推荐

  1. 使用Python一年多了,总结八个好用的Python爬虫技巧

    用python也差不多一年多了,python应用最多的场景还是web快速开发.爬虫.自动化运维:写过简单网站.写过自动发帖脚本.写过收发邮件脚本.写过简单验证码识别脚本. 爬虫在开发过程中也有很多复用 ...

  2. git 查看对比分支commit命令笔记

    git log  newheader(branch1) ^release(branch2) -- branch1 上比branch2多的commit 注意brnach2后面要--

  3. bing词典

    一.bug寻找 bug1:点击单词挑战之后选择四级词汇,然后一直狂击答案,点到一个时候就会出现一个情况:不管点击哪一个选项都不会跳至下一题,而且屏幕上方的已做题目数 x/20中的x会乱跳. bug2: ...

  4. 《Spring2之站立会议4》

    <Spring2之站立会议4> 昨天,对主界面进行了设计,编写了主界面的代码,把文本输入框,显示框,发送,关闭两个按钮的功能实现了: 今天,接着对主界面进行代码的编写,实现了界面的美化,从 ...

  5. 关于char存储值表示

    char里面-128的二进制表示为1000 0000,0的二进制表示为0000 0000 -127的二进制表示为1000 0001, 127的二进制表示为0111 1111. 从-127到-1和1到1 ...

  6. angularJS1笔记-(12)-自定义指令(compile/link)

    index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  7. js异步上传图片

    <!DOCTYPE html><html xmlns = "http://www.w3.org/1999/xhtml" ><head><m ...

  8. mysqldumpslow 分析slow query日志和explain分析mysql查询结构

    mysqldumpslow的使用:比如我们要查询按时间返回前5条日志信息,格式如下:mysqldumpslow -s t -t 5 /var/log/mysql/slowquery_20180303. ...

  9. HTTP压力测试工具wrk的安装及测试

    本次在VMware虚拟机的CentOS6.3系统中进行安装wrk压测工具,具体如下: 一.预先安装需求项 为了安装顺利,不受权限的限制,首先可以把用户切换为root用户# su + 输入root用户对 ...

  10. 增加kms计数

    @echo offset skms=10.15.68.62for %%i in (. . . . . . . . . . . . . . . . . . . . . . . . . .) do cal ...