宏的注意事项以及二义性
(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义允许嵌套
(8)字符串" "中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
(10)宏定义不存在类型问题,它的参数也是无类型的。
(1)#define NAME "zhangyuncong"
程序中有"NAME"则,它会不会被替换呢?
(2)#define 0x abcd
可以吗?也就是说,可不可以用不是标识符的字母替换成别的东西?
(3)#define NAME "zhang
这个可以吗?
(4)#define NAME "zhangyuncong"
程序中有上面的宏定义,并且,程序里有句:
NAMELIST这样,会不会被替换成"zhangyuncong"LIST
四个题答案都是十分明确的。
第一个,""内的东西不会被宏替换。这一点应该大都知道。
第二个,宏定义前面的那个必须是合法的用户标识符
第三个,宏定义也不是说后面东西随便写,不能把字符串的两个""拆开。
第四个:只替换标识符,不替换别的东西。NAMELIST整体是个标识符,而没有NAME标识符,所以不替换。
也就是说,这种情况下记住:#define第一位置第二位置
(1) 不替换程序中字符串里的东西。
(2) 第一位置只能是合法的标识符(可以是关键字)
(3) 第二位置如果有字符串,必须把""配对。
(4) 只替换与第一位置完全相同的标识符
还有就是老生常谈的话:记住这是简单的替换而已,不要在中间计算结果,一定要替换出表达式之后再算。
2、 带参宏一般用法
比如#define MAX(a,b) ((a)>(b)?(a):(b))
则遇到MAX(1+2,value)则会把它替换成:
((1+2)>(value)?(1+2):(value))
注意事项和无参宏差不多。
但还是应注意
#define FUN(a) "a"
则,输入FUN(345)会被替换成什么?
其实,如果这么写,无论宏的实参是什么,都不会影响其被替换成"a"的命运。
也就是说,""内的字符不被当成形参,即使它和一模一样。
那么,你会问了,我要是想让这里输入FUN(345)它就替换成"345"该怎么实现呢?
请看下面关于#的用法
3、 有参宏定义中#的用法
#define STR(str) #str
#用于把宏定义中的参数两端加上字符串的""
比如,这里STR(my#name)会被替换成"my#name"
一般由任意字符都可以做形参,但以下情况会出错:
STR())这样,编译器不会把“)”当成STR()的参数。
STR(,)同上,编译器不会把“,”当成STR的参数。
STR(A,B)如果实参过多,则编译器会把多余的参数舍去。(VC++2008为例)
STR((A,B))会被解读为实参为:(A,B),而不是被解读为两个实参,第一个是(A第二个是B)。
4、 有参宏定义中##的用法
#define WIDE(str) L##str
则会将形参str的前面加上L
比如:WIDE("abc")就会被替换成L"abc"
如果有#defineFUN(a,b) vo##a##b()
那么FUN(id ma,in)会被替换成void main()
5、 多行宏定义:
#define doit(m,n) for(int i=0;i<(n);++i)\
{\
m+=i;\
}
在C++中还引入了1个新的关键字const,以代替C语言中的宏定义。那么它们与C语言中的宏有什么区别呢?
#define宏与const和inline的比较。可以通过下面的两种形式来定义圆周率:
#define PAI 3.1415926 //宏定义
const float pai = 3.1415926 //常变量
在C语言中的宏在编译的时候,编译器只对宏进行简单的替换。在C++中通过const定义一个常变量与C语言中的宏定义相比,常变量具有拥有类型、可调试、可进行参数合法性检查等优点。
宏的优点包括:宏只是在预处理的地方把代码展开,不需要额外的空间和时间方面的开销,所以调用一个宏比调用一个函数(需要进栈出栈)更有效率。但是宏容易产生二义性,也不能访问对象的私有成员,这是宏的局限。
对于宏的二义性,来看看下面的例子。从下列选项中选择不会引起二义性的宏定义是:
A、 #indefine POWER(x) x*x
B、 #indefine POWER(x) (x)*(x)
C、 #indefine POWER(x) (x*x)
D、 #indefine POWER(x) ((x)*(x))
分析:
A.#indefine POWER(x) x*x
如果调用POWER(5+6),本意是 (5+6)*(5+6)=121,实际却是:5+6*5+6=41
B.#indefine POWER(x) (x)*(x)
如果调用POWER(5+6)/POWER(5+6),本意是得到结果为1,实际却是:(5+6)*(5+6)/(5+6)*(5+6)=11*11/11*11=121
C.#indefine POWER(x)(x*x)
如果调用POWER(5+6)+POWER(5+6),本意是 (11*11)+(11*11)=121+121=242,实际却是: (5+6*5+6)+(5+6*5+6)=41+41=82
D.没有二义性。