盡量以const和inline取代 define

2021-06-18 23:38:52 字數 1892 閱讀 8221

#define是屬於預處理器指令的,在effective c++中提到的條款1的標題如果改為「盡量以編譯器(compiler)取代預處理器(preprocessor)」或許更好,因為#define通常不被視為語言本身的一部分。

何為預處理器?

預處理器是編譯器把c++**編譯為機器指令之前執行的乙個過程,所有的預處理器都是#開頭,以便與c++語句區分開來。

何為#define指令?

該指令用於符號置換,其格式為#define  標示符 字串行。注意該語句不以分號結束。比如#define pi 3.1416就表示把pi置換為3.1416,這裡要注意的是雖然pi看起來和變數一樣,但pi和變數沒有半毛錢的關係,pi只是乙個符號或標誌,在程式**編譯前該符號會用一組指定的字元來代替。還要注意的是3.1416並不是乙個數值,而是乙個字串,因此不會進行型別檢查。而語句中的字串行可以是任意的字串行,而不僅僅是數字,比如#define pi hyong這樣的話在使用pi使就會用hyong來替換掉pi,當然hyong這裡會是乙個未定義的識別符號。

在使用#define指令定義常量時常常造成意想不到的錯誤

而在c++中可以使用const來聲名常量,比如const long double pi=3.1416;這樣的話pi將會始終保持為long double型別。c++會對它進行嚴格的型別安全檢查。這樣就可以避免因簡單的字元替換而出現的不可預料的錯誤。

(關於這個const在面試中也是常常被問到,記得一次我遇到面試官問我const的本質是什麼,我稀里糊塗說了大半天,他搖搖頭說沒有說到本質上去。最後他總結時說到如果你能說出const的本質是唯讀的我就不會接著問你那麼多的關於const的問題了。暈,平常還是思考的不夠細緻,沒有及時的總結,書看的少了。)

多本書(effective c++,c/c++高質量程式設計指南)上提到的乙個無用#define指令的常見例子是,以它來實現巨集------看起來像函式,卻又不會帶來函式呼叫所需要的成本。

乙個最經典的在多本書中提到的例子就是計算兩個數的最大值: #define max(a,b)  ((a) > (b) ? (a) : (b))

儘管我們可以像上面一樣通過加上括號來解決一些問題,但百密一疏,bug總還是會出現的,比如下面的用法就會讓事情很糟糕

int a = 5,b = 0;

max(++a,b);  //a會被累加2次

max(++a,b+10);   //a被累進1次

如果我們使用inline函式便可以獲得巨集帶來的高效率以及函式帶來的可預期行為和引數型別檢驗

inline int max(int a,int b)  

有時在筆試時有些考題是這樣的,讓你用巨集實現交換兩個數,**的是還不能用+,-,*,%。不知道這樣的考題有意義否?

如交換兩個數的巨集可以這樣實現

#define swap(x, y)  (x = x + y, y = x - y, x = x - y )

要注意的是當輸入的資料是不同種型別的話,這個巨集的結果是不對的。

如果要求你不能使用+,-,*,%,那麼就只能用位運算中的異或來運算,當然使用位運算會有更高的效率

#define swap(x, y)  (x ^= y, y ^= x, x ^= y)

但是這種實現只適用於整型資料。

就算我們適當的加上括號來防止一些錯誤,但上面所陳述的bug還是存在的

#define swap(x,y) ((x)=(x)+(y),(y)=(x)-(y),(x)=(x)-(y))

不思則以,細細想來,寫**還真不是一件容易的事,寫的越多有時越痛苦,感覺語言上就那些東西自己都掌握了,寫起**來總是出現我們所未知的錯誤。幸好在c++中有了const和inline可以幫助我們很好的解決上面的問題,不然真不知該腫麼辦!!!!

Effective C 盡量使用const

char greeting hello char p greeting const char p greeting char const p greeting const char const p greeting const在 號左邊,代表指標指向的物件是const的。如果在右邊,代表這個指標是c...

條款3,盡量使用const

條款03 盡可能使用 const const允許你指定乙個語義約束,也就是指定乙個 不該被改動 的物件。const如果出現在星號左邊,表示被指物是常量,如果出現在星號右邊,表示指標自身是常量 如果出現在星號兩邊,表示被指物和指標都是常量。如果被指物是常量,有些程式會將關鍵字const寫在型別之前,有...

Item 3 盡量使用 const

char greeting hello char p greeting non const data,non const pointer const char p greeting non const pointer,const data char const p greeting const po...