如何正确使用#define?
如何正确使用#define?
在这里我们讲讲#define的一些误用,因为上一片已经讲了它的主要作用,这篇主要是一些比较常见的宏陷阱。首先轻松一下。如下的一个经典例子。
#define private public
#include
using namespace std;
class c
{
private:
int i;
};
int main()
{
c c1;
c1.i=1;
cout<
#define 竟然让private如此的脆弱,但是却揭示了#define陷阱的根源,它仅仅是代码替换机制而已,除此之外,它什么都不是。
让我们步入正题,来看看下面的一个定义会产生一个什么样的错误?
#define f (x) ((x)-1)
如果这个是一个函数就没有什么问题
int f (int x) { return x-1; }
但是这里是define的世界,f(x)只见出现了一个可怕的空格
使得使得程序中如果出现了
f(10)
这个代码,最终就变成了
(10) (10-1)(10)这样一个奇怪的东西,当然这个代码倒是无法通过编译,还是可以检查出来的。算是让我们逃过了一次,下次就没有那么幸运了,让我们继续。
#define abs(x) x>0? x:-x (引用自C语言陷阱与缺陷)
这个代码有什么问题?也许大家也注意到了,我一直在用无数的()来写#define,不是因为我很喜欢()这个东西,而是当我在进行如下的调用的时候。
z = abs(a-b) //呜呼,这将产生什么东西呢?
答案是:
a-b>0? a-b : -a-b
这个显然不是我们要的结果,因为当a-b<0的时候将返回一个-a-b,要解决这个问题,我们就要使用()来解决。
#define abs(x) (x)>0? (x):-(x)
现在这个代码就可以正常的工作了。只要我们紧记#define是代码替换的机制,不要对它有任何的奢求,就会避免上面的问题。另外,因为宏不是一个类型,没有数据安全检查,在调试的时候也会产生障碍,所以,C++就一直提倡使用const和inline来替换#define,也许,#define真的会在历史的舞台上消失,但define在C语言时代留下的功绩却不应该忘记。
来自 http://community.csdn.net/Expert/topic/3195/3195102.xml?temp=.3936731