#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];
};