兩個都有問題····(原問題是define pi = 3.1416與int pi = 3.1416之間的比較)

寫法一:

如果用,就這麼寫

#define PI 3.14

這裡沒有等號,你那個define pi = 3.14直接玩崩,編譯錯誤。宏的話相當於所有出現PI的地方都換成3.14。宏的話有幾個點要注意

  1. 約定俗成宏都用大寫字母,請使用PI而不是pi。這樣別人一看到這個就知道是個宏
  2. 宏發生作用是在編譯之前,程序認為所有出現PI的地方都是3.14。所以如果你寫一個 PI*2,在編譯器眼中就是3.14*2。
  3. 宏寫的太複雜容易玩崩。因為編譯器不檢查宏的內容,編譯錯誤可能會很詭異,還會提高其他人閱讀代碼的難度
  4. 多用括弧!要不然可能會出現很多奇奇怪怪的問題(感覺評論提醒)

寫法二:

如果用const變數,就這麼寫

const double pi = 3.14;

這裡pi就是個普通的const double變數。這個pi就是跟其他變數一樣,存在內存裡面。因為是const所以不能修改。你上面那個int pi=3.14,直接等於把pi設為了3。同時沒有const前綴,意味著這個pi可能被修改,不安全。

寫法三:

評論區提到了常量更應該使用constexpr關鍵詞。對此我表示贊同。下面這種寫法更加嚴謹。請注意,constexpr要求C++11或者更高版本。

constexpr double pi = 3.14;

事實上const更應該理解為只讀。在程序運行中,const變數並不會被修改,即運行時常量(runtime constant)。constexpr則為編譯時常量(compile-time constant),意味著編譯器在編譯的時候就能知道這個常量真正的值。對於pi來說,更應該選用編譯時常量的constexpr。

不過即使你用const double pi = 3.14這個寫法,也不會有任何問題,畢竟變數初始化的時候已經寫死了值為3.14。同時constexpr因為是C++11標準才提出,這個關鍵詞在一些老環境會報錯。

總結:

正常來說C++裡面我們更推薦const變數(或者constexpr),而不是#define。基本上原因上就是

  1. #define沒有namespace也沒有class範圍,全局都一樣。相比較起來const變數可以重載,也可以是局部變數。不過這個對於PI這种放之四海皆準的常量來說直接用宏問題不大。
  2. #define中的內容編譯器不檢查錯誤,編譯報錯可能很詭異,提高了debug難度。

宏的優勢主要在於減少內存消耗,程序運行時減少取內存操作。


根據effective C++作者的建議,能用const變數代替define的,都用const變數。

我本來想說一個"優點",卻沒想到發現一個問題,已在stackoverflow上提問,坐等大神回答。

#define PI 3.1416
#define STRING(x) #x
#define STRING_PI STRING(PI)

void test()
{
string sPI = STRING_PI;
cout &

MACRO definition both for a number and a string?

stackoverflow.com圖標

已經有答案了

#include &

#define Q(x) #x
#define QUOTE(x) Q(x)

#define PI 3.1416
#define STRING(x) QUOTE(x)
#define STRING_PI STRING(PI)

#include &

void main()
{
std::string sPI = STRING_PI;
std::cout &

這麼做的好處就是少一次從數字到文字的轉換。


前一個報編譯錯誤,後一個就是3,計算結果不對。


沒任何優勢

一堆人說宏佔用內存少,都是錯的。對任何不太古老的編譯器來說,編譯出來的結果是一樣的,這種程度的優化是最最基本的了。


這哪個都不對啊?建議你回去重讀課本。


推薦閱讀:
相关文章