尽量以const和inline取代#define

#define是属于预处理器指令的,在Effective C++中提到的条款1的标题如果改为“尽量以编译器(compiler)取代预处理器(preprocessor)”或许更好,因为#define通常不被视为语言本身的一部分。

何为预处理器?

预处理器是编译器把C++代码编译为机器指令之前执行的一个过程,所有的预处理器都是#开头,以便与C++语句区分开来。

何为#define指令?

该指令用于符号置换,其格式为#define  标示符 字符序列。注意该语句不以分号结束。比如#define PI 3.1416就表示把PI置换为3.1416,这里要注意的是虽然PI看起来和变量一样,但PI和变量没有半毛钱的关系,PI只是一个符号或标志,在程序代码编译前该符号会用一组指定的字符来代替。还要注意的是3.1416并不是一个数值,而是一个字符串,因此不会进行类型检查。而语句中的字符序列可以是任意的字符序列,而不仅仅是数字,比如#define PI HYONG这样的话在使用PI使就会用HYONG来替换掉PI,当然HYONG这里会是一个未定义的标识符。

在使用#define指令定义常量时常常造成意想不到的错误

而在C++中可以使用const来声名常量,比如const long double PI=3.1416;这样的话PI将会始终保持为long double类型。C++会对它进行严格的类型安全检查。这样就可以避免因简单的字符替换而出现的不可预料的错误。

(关于这个const在面试中也是常常被问到,记得一次我遇到面试官问我const的本质是什么,我稀里糊涂说了大半天,他摇摇头说没有说到本质上去。最后他总结时说到如果你能说出const的本质是只读的我就不会接着问你那么多的关于const的问题了。晕,平常还是思考的不够细致,没有及时的总结,书看的少了。)

多本书(Effective C++,C/C++高质量程序设计指南)上提到的一个无用#define指令的常见例子是,以它来实现宏------看起来像函数,却又不会带来函数调用所需要的成本。

一个最经典的在多本书中提到的例子就是计算两个数的最大值: #define max(a,b)  ((a) > (b) ? (a) : (b))

尽管我们可以像上面一样通过加上括号来解决一些问题,但百密一疏,bug总还是会出现的,比如下面的用法就会让事情很糟糕

int a = 5,b = 0;

max(++a,b);  //a会被累加2次

max(++a,b+10);   //a被累进1次

如果我们使用inline函数便可以获得宏带来的高效率以及函数带来的可预期行为和引数型别检验

inline int max(int a,int b)   {return a > b ? a : b;}

有时在笔试时有些考题是这样的,让你用宏实现交换两个数,变态的是还不能用+,-,*,%。不知道这样的考题有意义否?

如交换两个数的宏可以这样实现

#define swap(x, y)  (x = x + y, y = x - y, x = x - y )

要注意的是当输入的数据是不同种类型的话,这个宏的结果是不对的。 

如果要求你不能使用+,-,*,%,那么就只能用位运算中的异或来运算,当然使用位运算会有更高的效率

#define swap(x, y)  (x ^= y, y ^= x, x ^= y)

但是这种实现只适用于整型数据。

就算我们适当的加上括号来防止一些错误,但上面所陈述的bug还是存在的

#define swap(x,y) ((x)=(x)+(y),(y)=(x)-(y),(x)=(x)-(y))

不思则以,细细想来,写代码还真不是一件容易的事,写的越多有时越痛苦,感觉语言上就那些东西自己都掌握了,写起代码来总是出现我们所未知的错误。幸好在C++中有了const和inline可以帮助我们很好的解决上面的问题,不然真不知该肿么办!!!!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值