- 预处理命令:
常见的预处理命令有:
#define
#include
#ifndef
- 宏定义分类,大致分两种:
类似对象的宏定义:
#define MAXSZIE 10000
带参数的宏:
#define add(x,y) x+y
- 宏表达式的调用:
类似于普通函数间的调用:
#define plus(x,y) add(x,y)
#define add(x,y) ((x)+(y))
//调用:
plus(plus(a,b),c);
//调用结果:就是按照顺序嵌套:
//最终=((c)+(((b)+(a)))
- 取消宏定义:
#undef name
- 重新定义宏:
#define NULL 0
#define NULL -1
//当然也可以对带参数的宏进行重定义,不过必须保证格式完全相同
//并不推荐这样做 - 宏展开的优先级错误–易错!
#define Square(x) x*x
#define square(x) (x)*(x)
//上述两个定义的区别体现在当x是一个表达式的时候:比如
Square(3+a)
//得到 3+a*3+a
square(3+a)
//(3+a)*(3+a)
//另外,还要注意宏定义和++运算符联系在一起的时候,上述两个函数的含义又不一样了,取决于不同的编译器
a=3;
b=Square(a++);
c=square(a++);
//b得到的可能是3×3,结束后a=4;
//而c得到的可能是3×4,结束后a=5;
- 使用ifndef避免错误
为了防止在不知道的情况下重定义,我们应该使用如下判断语句:
#ifndef maxsize
#define maxsize 20
#endif
- 普通函数和define的区别
为什么我应该用内联函数?而不是原来清晰的 #define 宏?
因为#define宏定义函数是在四处是有害的:
和 #define 宏不同的是,内联函数总是对参数只精确地进行一次求值,从而避免了那声名狼藉的宏错误。换句话说,调用内联函数和调用正规函数是等价的,差别仅仅是更快:
// 返回 i 的绝对值的宏
#define unsafe(i) ( (i) >= 0 ? (i) : -(i) )
// 返回 i 的绝对值的内联函数
inline
int safe(int i)
{
return i >= 0 ? i : -i;
}
int f();
void userCode(int x)
{
int ans;
ans = unsafe(x++); // 错误!x 被增加两次
ans = unsafe(f()); // 危险!f()被调用两次
ans = safe(x++); // 正确! x 被增加一次
ans = safe(f()); // 正确! f() 被调用一次
}
和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的转换。
宏定义复杂函数是有害的;非万不得已不要用