請問#define PI 3.1416比float pi=3.1416有什麼優勢呢?
兩個都有問題····(原問題是define pi = 3.1416與int pi = 3.1416之間的比較)
寫法一:
如果用宏,就這麼寫
#define PI 3.14
這裡沒有等號,你那個define pi = 3.14直接玩崩,編譯錯誤。宏的話相當於所有出現PI的地方都換成3.14。宏的話有幾個點要注意
- 約定俗成宏都用大寫字母,請使用PI而不是pi。這樣別人一看到這個就知道是個宏
- 宏發生作用是在編譯之前,程序認為所有出現PI的地方都是3.14。所以如果你寫一個 PI*2,在編譯器眼中就是3.14*2。
- 宏寫的太複雜容易玩崩。因為編譯器不檢查宏的內容,編譯錯誤可能會很詭異,還會提高其他人閱讀代碼的難度
- 多用括弧!要不然可能會出現很多奇奇怪怪的問題(感覺評論提醒)
寫法二:
如果用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。基本上原因上就是
- #define沒有namespace也沒有class範圍,全局都一樣。相比較起來const變數可以重載,也可以是局部變數。不過這個對於PI這种放之四海皆準的常量來說直接用宏問題不大。
- #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,計算結果不對。
沒任何優勢
一堆人說宏佔用內存少,都是錯的。對任何不太古老的編譯器來說,編譯出來的結果是一樣的,這種程度的優化是最最基本的了。
這哪個都不對啊?建議你回去重讀課本。
推薦閱讀: