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),这样对调用者来说才是实用的。
宏的写法有很多值得注意的地方,这几点只是冰山一角,是自己平时常遇到的问题。
浙公网安备 33010602011771号