首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C/C++程序中的一把双刃剑 - 宏,该如何解决

2012-02-22 
C/C++程序中的一把双刃剑 - 宏在C中使用宏的确是一个非常好的代码手段,可以大量的减少代码量,提高阅读性,

C/C++程序中的一把双刃剑 - 宏
在C中使用宏的确是一个非常好的代码手段,可以大量的减少代码量,提高阅读性,通过对一些常用代码的归类写成宏,作用巨大.  
例如如下代码:  

if(((t-> flag   &   S_FLAG1)   ||   (t-> flay   &   S_FLAG2))   &&   t-> type   ==   T_TYPE1)  
...  
条件部分如果多次使用到,那么我们完全可以写如下的宏  
#define   IsXXXX(t)   (((t-> flag   &   S_FLAG1)   ||   (t-> flay   &   S_FLAG2))   &&   t-> type   ==   T_TYPE1)  
这样上面的代码就成了  
if(IsXXXX(t))  
...  
代码少了很多,而且可读性也增加了很多.  
还有一个代码,C中分配一个结构,一般如下代码:  
p=(STRUCT*)malloc(sizeof(STRUCT));  
是否可以更加漂亮呢?创建一个宏,如下:  
#define   new(t)   (t*)malloc(t)  
这样上面的代码就变成了  
p=new(STRUCT);  
是否有C++的风格了?

但是有利必有弊,宏一旦使用不当反而会产生严重的后遗症,下面随意说几点.  
1.给宏赋予太强大的功能,几乎所有的编译器以及大部分的IDE无法展开和定位宏中的代码,所以一旦产生错误,很难调试,   如果真的需要最好还是用函数来封装.

2.宏名字起的不当,这是很致命的,会导致代码可读性大大降低,例如随意将前面例子中的IsXXXX定义为a,然后后面的代码中全是一堆的  
if(a(t))  
如果这样,键盘是少打了,但是已经完全没有了可读性,也许今天写的这个宏,明天你就忘记这个宏是做什么了.   同时过于简单的名字也会导致同名但是功能不同的宏大量出现,使得代码更难看懂.

3.宏的随意undef,这个是一个很不好的习惯,代码量一旦达到了一定程度,会导致极度的混乱.  
例如在某个.h文件中定义了IsXXXX,然后在某个.c中如下使用  
#undef   IsXXXX  
#define   IsXXXX(t)   (((t-> flag   &   S_FLAG3)   ||   (t-> flay   &   S_FLAG4))   &&   t-> type   ==   T_TYPE2)  
这个对于以后的维护修改埋下了极大的隐患.

4.重名,说起来这个算是很多编译器的问题,如果将一个宏的名字和一个变量的名字重名了,那么很多的C   Compiler默认状态下不会报警或报错.  
例如:  
int   a;  
...  
#define   a   b  
这种错误有时候简直可以让人发疯!!!

5.宏的嵌套使用,不是不能这么用,由于宏屏蔽了实际代码,如果宏-> 宏,那么即使你的宏写的够漂亮明了,恐怕天长日久也就忘记里面具体的逻辑,一旦想修改就很麻烦,所以要小心使用.

到了C++年代,宏的使用少了很多,不过模板几乎就是宏的升级.  
说起来在MFC中消息映射就是一套极具特色的宏,如果不了解它也就算了,但是当你看懂了就会感叹宏的魔力!

转JavaEye


[解决办法]
除了为了跨平台的需要以及Debug之外,几乎不用宏。
[解决办法]
偶一般只在条件编译的时候才使用宏,其它的都可以用const, inline来代替,呵呵
[解决办法]
okokok
[解决办法]
宏在C中相当普遍. C++其实极度想消除宏的, 只是目前做不到完全消除而已. 对于#define这样的宏, 我们可以用const,enum或者inline来代替.但是对于#include, #ifdef等宏来说, C++目前还只能忍痛继续使用(也许未来的C++会推出新的关键字来代替这些宏). C/C++的程序员不可能避免与宏打交道. 其实使用好宏并不是非常难得事情. 只要我们循规蹈矩, 不要过分聪明, 那么宏也就不会产生太大危害. 对于#define宏的使用, 有两件事情需要注意:
1, 尽量不要在宏中把宏参数展开两次. 如果一定要展开两次, 那么请小心使用宏参数, 不要让这样的宏参数变成表达式.
典型的宏就是: #define max(a,b) ((a) > (b) ? (a) : (b))
对于这样的宏,我们没有办法不让它的宏参数展开两次.因此当我们知道max宏会把参数展开两次的时候,我们要小心使用该宏.不要写出像max(a++, b=GetValue())这样的语句.当然,这样的宏最好写成inline函数.
2, 如果有多行的宏,尽量用do...while把它们包起来.
#define multi_macro() \
do \
{ \
statement1; \
statement2; \
} while (0)
这样写比把单独的多行语句裸露在外面要好很多.

总的来说, 宏要少用, 但也不能不用. 用好宏能够事倍功半, 用不好则焦头烂额.

[解决办法]
學習下
[解决办法]
不可滥用,不可不用。
宏的一些基本功能可以被 inline, const, enum 取代,但是一些高级的用法还是无可替代的需要用到宏。用得好的话一样可以让代码清晰、简洁、易懂。

热点排行