#define 的注意用法

来源:互联网 发布:白云网络 编辑:程序博客网 时间:2024/04/29 19:37

在这里我们讲讲#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