2011-11-16
先吐槽,在csdn排版很纠结......blog都这样么?
预处理器两个重要之处,管理长量和宏函数。相当于 c++理的 const 和 inline.
宏函数很容易出错,妇孺(限程序员内)皆知!既使都用括号括起来!(括号作用是预防默认优先级有关的问题)
#define Max(x,y) (((x)>=(y))?(x):(y))
问题用法:
for (int i = 0; i < N; i++)
biggest = Max(biggest , x[i++]);
因为i++了两次,
((biggest)>=(x[i++]))?(biggest):(x[i++]) , i++有副作用.
第二个问题,宏函数展开后表达式或许会很长,并不节省开销。
宏并不是语句!!
考虑定义assert宏,参数是一个表达式,如果表达式为0,终止程序,给出一条错误消息。
第一个版本:(考虑使用者会加分号,所以定义时没加分号)
#define assert(e) if(!e) assert_error(__FILE__, __LINE__)
问题用法(展开会发现if else 控制变了)
if(x > 0 && y > 0)
assert( x > y);
else
assert(y > x);
第二个版本:
#define assert(e) { if(!e) assert_error(__FILE__, __LINE__);}
但用法变成了
if(x > 0 && y > 0)
assert( x > y)
else
assert(y > x)
没有分号会显得很怪异
正确版本(很难想到,不直观)定义类似一个表达式,而不是类似语句
#define assert(e) ( (void)( (e) || assert_error(__FILE__, __LINE__) )
宏并不是类型定义!!
最好用 typedef
#define T struct foo*
T a , b; //a是指针,b却是个结构
Max 的正确版本(抄的答案,没想出来,自己想的时候局限在了 #define 语句上了.)
static int max_temp1, max_temp2;
#define Max(x,y) (max_temp1 = (x), max_temp2 = (y),max_temp1>max_temp2?max_temp1:max_temp2)
可惜 Max(x,y) 不能嵌套调用,Max嵌套调用的情况下,我们不可能让它正常工作! 可能这就是宏固有的缺陷吧!
老老实实的用 inline吧