新买的《Effective c++>>,每天学习一点点。
今天大致看了条款02的内容,条款02的主要内容就是尽量用const,enum,inline替换#define。
(一)用const 替换#define
(1)const常量有数据类型,而宏没有数据类型。编译器可以对const进行类型检查,而对#define只进行字符替换,没有类型检查,并且在字符替换中可能会产生意料不到的错误(边际效应)。例如:
#define N=5;
#define M 6+N
M*N=6+5*5 并不是M*N=(6+5)*5
(2)可以对const常量进行调试,但是不能对#define定义的宏常量调试。
(3)当定义局部变量时,const作用域仅限于定义局部变量的函数体内。但用#define时其作用域不仅限于定义局部变量的函数体内,而是从定义点到整个程序的结束点。但也可以用#undef取消其定义从而限定其作用域范围。
(二)用enum替换#define
(1)在比较老的编译器上不允许static 成员在其声明式上或得初值,而编译器在class编译器间需要一个class常量,可以用枚举类型。
(2)如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型。
(三)用inline替换#define
(1)内联函数和普通函数相比可以加快程序的运行速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中,而宏只是一个简单的替换。
(2)内联函数要做参数的类型检查,宏没有。
(3)#define定义的宏有时存在边际效应。
如
#define SQR(x) (x*x)
int a,b=3
a=SQR(b+2) 计算结果是11而非25
(4)函数的副作用
如果一个参数在定义中出现了多次,它可能被多次求值。如果调用是的实际参数带有副作用,结果将是一个难以捉摸的错误。
如:
#define isupper(c) ((c) >= 'A' && (c) <= 'z')
while(isupper(c=getchar())
...
那么每当遇到一个大于等于A的字符,程序就会将它丢掉,而下一个字符讲被读入并去和Z做比较。(程序设计实践中的例子。
宏和内联函数的用法:
宏:
1不能以分号结束,注意给参数加上括号
2保证参数值求值一次。
内联函数:
1一个函数被重复调用
2函数只能简单的几行,且函数内不包含for,while,switch语句。
阅读(1260) | 评论(0) | 转发(0) |