微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > C语言宏定义中#和##的作用

C语言宏定义中#和##的作用

时间:10-02 整理:3721RD 点击:
本文由dongeasy收集整理,原文链接:http://www.dongeasy.com/software-development/embedded-system/2013.html

在宏定义中#和##的作用是:前者将宏定义的变量转化为字符串;后者将其前后的两个宏定义中的两个变量无缝拼接在一起转化为字符串。

1.   #: 在宏定义中,将其后的变量,转化为字符串。

eg:  #define  str(s)      #s

输出: helloworld , 就可以通过这样的的调用, printf( str(helloworld) );

2. ## : 在宏定义中,将其前后的两个变量拼接在一起。

eg: #define v(a,b,c,d)       0xa##b##c##d

//将四个字节的十六进制的数据转化为一个十六进制的整型数据

int    a  =  v(CF,AB,B0,BC);   // 即 a = 0xCFABB0BC

3. 两者的共性: 能够阻止宏定义的递归展开。可以通过中间的转换的宏,来实现参数宏的展开。

测试例子:

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <unistd.h>
  • #define ROOT "/mnt/sd/"
  • #define NAME "kernel.img"
  • #define path(dir,name) dir##name
  • #define print(format,args...) printf(format,##args)
  • #define test(name) #name
  • enum
  • {
  •     MON = 1,
  •     TUE = 2,
  •     SUN = 7
  • };
  • int main(int argc, char *argv[])
  • {
  •     //printf("macro PATH = %s\n", PATH);
  •     //printf("path(dir,name) = %s\n", path(ROOT,NAME));
  •     printf("path(dir,name) = %s\n", path(RO,OT));
  •     //printf("macro TEST = %s\n", TEST);
  •     printf("test(name) = %s\n", test(NAME));
  •     printf("test(MON) = %s\n", test(MON));
  •     //printf("#MON = %s\n", #MON);
  •     print("%s%s\n", ROOT,NAME);
  •     return 0;
  • }

测试结果:

  • ~/test$ ./macro_sign
  • path(dir,name) = /mnt/sd/
  • test(name) = NAME   #宏不会递归展开
  • test(MON) = MON    #可以很方便地实现枚举变量的字符串显示
  • /mnt/sd/kernel.img   # ##符号的特殊用法
实际应用

使用#和##宏符号的作用定义最简单的日志接口,如下:

  • #define SLOG(level,format,args...) \
  •      do{printf("[%s]",#level);printf(format,##args);}while(0)
  • SLOG(ERR,"%s",strerror(errno); // 调用方式,不需要定义ERR宏,接口会自动打印为字符串

这个宏可以很方便地替换在项目中使用的正式日志接口,用来保持模块的独立性,便于模块的测试。


嵌入式培训www.arm8.net我是来学习的!非常感谢这个论坛!我来这里拿点资料

讲得挺好,一般工程师可能都不懂。

##这个操作符不错

来看看每天坚持学习北京嵌入式培训www.arm8.net

这个不错,以后用的时候可以尝试下

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top