锁定老帖子 主题:双刃剑 - 宏
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-03-20
例如如下代码: 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中消息映射就是一套极具特色的宏,如果不了解它也就算了,但是当你看懂了就会感叹宏的魔力! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-03-21
写得不错,不过 "不过模板几乎就是宏的升级." 这句怎么理解?
|
|
返回顶楼 | |
发表时间:2007-03-21
模板使用的方法和宏的原理是类似的,只是编译器对模板作了很多特殊语法实现而已
|
|
返回顶楼 | |
发表时间:2007-03-21
宏不能算语言的一部分。
宏和模板都是用来产生代码的工具。。。 |
|
返回顶楼 | |
发表时间:2007-03-21
这个嘛,当然是语法
但是作用吗可以看作用来产生代码 |
|
返回顶楼 | |
发表时间:2007-03-21
这么好的文章,也发到C++圈子吧。:D
|
|
返回顶楼 | |
发表时间:2007-03-22
模板其中一个作用就是 编译时生成代码, 宏则是编译是展开代码。
虽然功能类似,不过模板的逻辑性要强些,可以自己去设计按某种特殊条件生成特殊的代码。 两个相同的地方,都是静态处理代码,运行时不起作用。 |
|
返回顶楼 | |
发表时间:2007-03-22
jack 写道 模板其中一个作用就是 编译时生成代码, 宏则是编译是展开代码。
虽然功能类似,不过模板的逻辑性要强些,可以自己去设计按某种特殊条件生成特殊的代码。 两个相同的地方,都是静态处理代码,运行时不起作用。 宏是预编译时,应该把这个部分分开来看,它必须单独进行一次。经过预编译以后,只剩下#line宏了。。这才是给编译器看的。 |
|
返回顶楼 | |
发表时间:2007-03-23
#define 和#include 一样都是预处理器指令,而预处理器是编译过程中单独执行的第一个步骤.
宏还有几个很有意思的用法: 1 #define print(tmp) printf(#tmp " = %d\n",tmp) 调用这个宏时 这里就相当于 printf("tmp = %d\n",tmp); 2 #define join(a,b) a##b 比如调用printf("%d",join(1,2)); 这时就会打印出12 或者int join(a,1)=1; printf("%d",join(a,1)); 这样就会打印出1; 还有一个就是 我怎么感觉 define 有些地方和FP中的lambda有些相似. |
|
返回顶楼 | |
发表时间:2007-03-24
所以纯一些的说
编译器并不知道宏的存在 预处理器都把活干完了 模板才是编译器的噩梦 |
|
返回顶楼 | |