【理論實踐】#define 和const帶給開發者的影響區別

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章