在程序被编译器编译之前,宏会被预处理器执行文本替换,编译器或许根本看不到宏。
例如 #define ASPECT_RADIO 1.653,如果因为此常量出现问题,编译器也许会提到1.653而不是ASPECT_RADIO。十分不利于分析调试。
解决之道是以一个常量替换之const double AspectRadio=1.653。使用常量可能比使用宏产生更小的目标码。因为预处理器“盲目的将ASPECT_RADIO替换为1.653”可能导致目标码出现多份1.653。
#define并不重视作用域。从宏被预处理器看到之后一直存在知道被#undef。
#include <iostream.h> void fun() { #define SCORE 36 cout<<SCORE<<endl; } int main() { fun(); cout<<SCORE<<endl; return 0; }
enum hack 理论依据:属于枚举类型的数值可以当作ints使用。
class GamePlayer { private: enum{StuNum=5}; int score[StuNum]; };
enum比较像#define,但是有了作用域的限制。并且取enum或#define的地址通常是不合法的。
以#define实现函数宏的潜在危害
#include <iostream.h> #define ADD5(a) a+5 void main() { int b=5; cout<<ADD5(b)*2<<endl; }
上面程序中,我们通过宏将b+5,然后再乘以2,应该得到10,结果输出15,原因就是因为宏是单纯的文本替换。
ADD5(b)*2被替换为b+5*2,竟然先执行了乘法,所以定义宏,最好加上()号。
#include <iostream.h> //a,b加括号保险 #define GET_MAX(a,b) (((a)>(b))?(a):(b)) void main() { int a=5,b=0; cout<<GET_MAX(++a,b)<<endl; }
猛然看去。应该输出6,结果却输出7.
GET_MAX宏被文本替换后。
cout<<GET_MAX(++a,b)<<endl;=====>>>cout<<(((++a)>(b))?(++a):(b))<<endl;
所有条件为真的情况下,a被加了2次。