C语言中的宏的写法

  C语言中宏是经常用到的,虽然经历C++的出现,const,inline等在C++中出现的技术取代了宏,但在C语言的程序中,特别是某些底层程序,如内核,驱动程序等等,宏有着不可替代的作用。

  宏本身不是函数或变量,没有具体名称,只是展开,这就要求宏的写法要特别注意,很容易出错。

 

1  执行体尽量用括号括起来

    
#define MAX(x,y) (x)>(y)?(x):(y)

这段宏看起来没什么问题,但在特定表达式中

printf("%d\n",20+MAX(3,5));

我们期待得到25,但执行结果为3 ,因宏展开后表达式为 20+(3)>(5)?(3):(5),算数运算符优先级高于比较运算符,就变成20+3>5?3:5,23自然大于5,返回只能是3

宏改为

#define MAX(x,y) ((x)>(y)?(x):(y))

就避免了这个问题

 

2 尽量写通用的宏,并支持表达式

上面那个宏换一种方式调用:

int i=3,j=5;

printf("%d\n",MAX(i++,j++));

本意是得到最大值后再自增,此时的输出为5,并未做自增操作,但结果却是6,也是因为操作符优先级的问题。

改成

#define MAX(x,y) ({

  int _x = x; \

  int _y = y; \

  _x >_y?_x:_y; \

})

这样就得到正确的数据了。但这种宏只能用于整数,对于其他类型,我们不可能写那么多宏,可以填一个参数

#define MAX(type,x,y) ({

  type _x = x; \

  type _y = y; \

  _x >_y?_x:_y; \

})

 

调用的时候:MAX(int,3,5)  MAX(float,3.4,5.6)等等,但这种方法调用并不友好。

 

3 利用编译器的特殊关键字

GCC对类型有个关键字为typeof,可以直接获取参数类型,这样就省去了调用时指定类型的麻烦。

 

#define MAX(x,y) ({

  typeof(x) _x = x; \

  typeof(y) _y = y; \

  _x >_y?_x:_y; \

})

调用就变成MAX(3,5)  MAX(3.4,5.6),这样对调用者来说才是实用的。

 

宏的写法有很多值得注意的地方,这几点只是冰山一角,是自己平时常遇到的问题。

posted @ 2019-01-06 15:44  cablink  阅读(1471)  评论(0)    收藏  举报