C语言好宏定义细节注意

在代码展开这块,C语言有别于C++;C++除了能够同C语言一样,使用宏,进行代码展开外,还可以使用 inline定义的方式;就宏定义而言,使用时,能够让代码的可读性变的更清晰;但是,在使用的时候,如果稍有不慎,就会出现问题,现在就宏定义的问题进行简单的归纳总结:

       一般用宏去定义一个常量,这是最简单的宏定义,也基本上没有多少雷区,就不进行说明;现在主要介绍类似于函数的宏定义中,隐藏的危险;

#define abs(x)  x>0 ? x : -x;

这个宏定义看似没有问题, 但是当我们这样调用:abs(a-b) ; 他对应的展开为:a-b>0? a-b:-a-b;

这里,如果a-b<0 ,则,输出的结果为-a-b , 而不是我们期待的 -(a-b);

换一个使用:abs(a) + 1;  调用时,对应的展开为 a>0? a : -a+1; 也不是我们想要的结果;

所以,为了避免这样的情况发生,我们定义宏的时候,一定要带上括号,包括整体的括号,和每个变量的括号。

例如:abs(a)  ((a) > 0 ? (a) : (-a));

这样定义看似没有问题了,但是在有些时候,还是会有问题;现在举个常用的例子

#define MAX(a, b)  ((a) > (b) ? (a) : (b)); 

int iBuff[10] = {1,2,3,4,5,6,7,8,9,10};

int biggest = buff[0];

int i = 0;

int n = 10;

while(i < n)

{

        biggest = MAX(biggest, x[i++]);

}

明显,在执行的时候,发生的情况,并不是我们预期的;在宏展开的时候,可能会对变量i进行两次自加操作。

类型定义相关宏定义:

#define  T1 struct foo *

typedef struct foo * T2;

T1 和T2都是宏定义,虽然看起来相同,并且很多时候应用的结果都一样,但是两者还是有区别的,现在举个例子,如下:

T1 a, b;

T2 a, b;

展开的结果分别为:struct foo *a, b;  和 struct foo *a, *b;

很明显,两者的语义已经发生了变化;前者定义了两个变量,一个为foo 结构体指针,一个为结构体对象;后者则定义了两个结构体指针。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值