关于宏#define使用陷阱总结

宏定义发生在预编译阶段,简单的说本质就是文本替换。使用时,有以下注意事项:

1,用宏定义表达式时,要使用完备的括号

如一下三个例子:

#define ADD(a,b) a+b

#define ADD(a, b) (a + b)

#define ADD(a, b) (a) +(b)

这三种定义,全部都是不符合要求的。陷阱如下:

在计算ADD(a,b)*ADD(c,d)时,显然第一种出问题了。

#define MULTIPLE(a, b) (a*b) 在计算(a+b)*c时,调用MULTIPLE(a+b,c)得到的结果错误。

因此一定要使用完备的括号,如下示例:

#define ADD(a,b) ((a) + (b))

2,使用宏定义,不允许参数发生变化,这也就是带参数的宏定义和函数的区别:

如下测试源码:

#include <stdio.h>
#define sqrt(a) ((a)*(a))
int fsqrt(int a)
{
	return a*a;
}
int main()
{
	
	int a = 10, b = 10;
	int r1, r2;
	 r1 = sqrt(a++);
	 r2 = fsqrt(b++);
	printf("a = %d, b = %d, r1 = %d, r2 = %d\n", a, b, r1, r2);
	return 0;
}


最终的结果是a = 12; b = 11; r1 = 100; r2 = 100; 以上结果在vc6.0下获得。之所以a变成12,是因为在替换的时候,a++被执行了两次。要避免这种行为,就要使宏参数不发生变化。

如:a++; r1 = sqrt(a), 一切就ok了!

3,使用大括号将宏定义包含的多条表达式括起来。

如下示例:

#include <stdio.h>
#define INITIAL(a, b)\
	a = 0;\
	b = 0;
int main()
{
	
	int a[5], b[5] ;
	int i;
	for(i=0; i<5; i++)
	INITIAL(a[i], b[i]);

	printf("a = %d, b = %d\n", a[0], b[0]);
	return 0;
}


结果打印a是正常的,但打印b却是未初始化的结果。因为简单的文本替换,不能保证多条表达式都放到for循环体内。(这里,如果单独初始化一个变量,没有for循环时没有问题的。)上述的宏定义应改为:

#define INITIAL(a, b)\
	{\
    a = 0;\
	b = 0;\
	}


注意这个“\”号哦,表示下面的一行和当前行在预编译时被认为在同一行。

最后,再简单对比下#define和 typedef的区别,#define发生在预编译阶段, typedef发生在编译阶段,可参考http://topic.csdn.net/t/20030810/14/2129718.html。更多细节上的区别,稍后再谈。

不对之处,大家多指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值