预处理器之宏的使用

        我们知道C程序在编译过程之前,C语言预处理器首先对程序代码作了了必要的转换处理。 宏在C程序中是非常有用的,比如我们可以通过修改宏定义来修改在程序中出现的所有实例。同时通过宏定义还可以免去函数调用带来的重大系统开销。

虽然宏定义非常有用,但是宏定义也是非常容易出错的。主要表现为以下几点:

1、 不能忽视宏定义中 的空格

比如在下面的宏定义中

       #define f  (x)  ((x)-1) 因为在f和(x)之间有一个空格,所以这个宏定义实际代表的是f 代表(x) ((x)-1),这和我们预想的f  (x)代表((x)-1)相去甚远。

     ****这里需要特别注意的是,虽然在宏定义的时候空格不能忽视,但是当我们在程序中用到宏定义时,空格却是可以忽略的,比如我们的宏定义中#define f(x)  x+3;在程序中我们可以用f (x)来调用该宏,这时候是没有任何错误的。

2、宏并不是函数

因为宏从表面上看其行为与函数非常相似,我们有时候会把他们视为完全相同。然而情况却并非如此。

比如我们定义一个宏 #define max(a,b)    a>b?a:b;  但是当我们计算max(x-z,y-z)时,宏展开后的结果却和我们预想的相去甚远,展开为 x-z>y-z?x-z:y-z;  显然这不是我们想要的结果。因此在进行宏定义的时候我们最好都把每个参数用大括号括起来。同样整个结果表达式也应该用括号括起来,以防止当宏用于一个更大一些的表达式中可能出现的错误问题。

是不是这样的宏就没有任何问题了,当然不是!!!!!!!!!!!在宏调用中,如果一个操作数在两处被调用,就会被求值两次,比如我们定义的宏#define max(a,b)    a>b?a:b;  在进行宏调用时,max(x++,y++);中的x和y都用可能被++两次,解决这种问题的方法有两个,要么不使用宏调用,将宏改为函数,要么宏调用中的参数没有副作用。

3、宏并不是类型定义

很多编程者都喜欢用宏来定义一种数据类型,比如 :

#define FOOTYPE struct foo *

       FOOTYPE a;

       FOOTYPE b,c;

编程者本来的意图是将b,c都定义为指向结构的指针,而事实上将第二个声明扩展开为

struct foo * a,b;

这个语句中a被定义为一个指向结构的指针,而b却被定义为一个结构(而不是指针);

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值