#define STR 1.76333333预编译
const double STR = 1.76333333;
主要区别:
1、处理阶段不同
预编译可以简单的理解为替换代码,基本不会出错,靠前。
常量定义是合法的变量只是不可修改值,发生在编译和链接阶段
2、标识符号处理结果不同
预编译处理之后,标识舍弃,编译、链接和运行时绝对不会提示出原名称。
常量定义如果编译带符号编译,会写标识到编译输出文件的符号表,编译、链接和运行时可能会提示出原名称。
两者编写正确影响感觉不到,但如果出错了,尤其是大型工程,提示和追踪将差异化掉,举例看一下:
//#define STR 1.76333333
const double STR = 1.76333333;
//假设STR定义在其他文件里,经过复杂的引用关系引入进来
int main()
{
int arr[3];
cout << STR.c_str() << endl; #误以为STR是string
return 0;
}
main.cpp: In function ‘int main()’:
main.cpp:11:15: error: request for member ‘c_str’ in ‘1.76333333e+0’, which is of non-class type ‘double’
cout << STR.c_str() << endl;
^
make: *** [main] Error 1
常量定义版本的报错
main.cpp:12:15: error: request for member ‘c_str’ in ‘STR’, which is of non-class type ‘const double’
cout << STR.c_str() << endl;
^
make: *** [main] Error 1
很明显,前者的提示容易让人琢磨不透,后者更直观。
常量处理还有一个enum补偿法技巧,这会限定作用域在代码内,不占用空间同时符合封装,可以参考一下以下代码:
class A
{
//enum hack法 enum补偿法
enum { SIZE = 30 };
int m[SIZE];
//常量法
static const int SIZE2 = 30; //旧版编译器需要在类外定义赋值
int m2[SIZE2];
//宏定义法
#define SIZE3 30
int m3[SIZE3];
};