1樓:gunir
因為巨集這種東西就是簡單的字元替換,而且發生在預編譯階段。有多少人關注預編譯階段的事情。
而且巨集定義的常量,當你需要debug的時候完全見不到反彙編資訊,只有一串引數,這時候你就會懵逼。
2樓:果凍蝦仁
分場景,題主可能理解有誤。
如果是把巨集用來定義常數,那麼不建議使用。
如果是其他巨集用法,有時候只有巨集才能實現,那麼就無所謂是否建議使用了,因為沒別的招。比如條件編譯,你不用巨集,實現乙個試試。
3樓:Mimosa
巨集的情況,與模版的情況類似,功能都很強大,如果濫用,可讀性會很差。但是巨集的一些特性,比如識別符號的連線,轉化字串等,會為C/C++程式設計帶來很大的便利,尤其在大量資料列表方面。
#define VarDef(_n) myVar_##_n = #_n
>>>>
varDef(123);
等效myVar_123 = "123";
4樓:小林coding
最近正好在看 《Effective C++中文版第三版》,其中條款 2 就提及你所問的問題。
以下內容是我閱讀該書總結的筆記。
#define 是不被視為語言的一部分,它在程式編譯階段中的預處理階段的作用,就是做簡單的替換,將 A 內容替換成 B 內容。
#define PI 3.14
如上述的 PI 巨集定義,在程式編譯時,編譯器在預處理階段時,會先將原始碼中所有 PI 巨集定義替換成 3.14。
程式編譯在預處理階段後,才進行真正的編譯階段。在有的編譯器,運用了此 PI 常量,如果遇到了編譯錯誤,那麼這個錯誤資訊也許會提到 3.14 而不是 PI,這是會讓人困惑的,特別是在專案大的情況下。
解決之道是以 const 定義乙個常量替換上述的巨集(#define):
const
doulePi=
3.14
;作為乙個語言變數,Pi 肯定會被編譯器看到,出錯的時候可以很清楚知道,是這個變數導致的問題。
如果是定義常量字串,則必須要 const 兩次,目的是為了防止指標所指內容和指標自身不能被改變:
const
char
*const
myName
="小林coding"
;如果是定義常量 string,則只需要在最前面加一次 const,形式如下:
const
std::
string
myName
("小林coding"
);還有另外一點巨集無法涉及的,就是我們無法利用 #define 建立乙個 class 專屬常量,因為 #define 並不重視作用域。
對於 class 裡定義常量時,我們依然使用 static + const,形式如下:
class
Student
;const
intStudent
::num
;// static 成員變數,需要進行宣告
如果不想外部獲取到 class 專屬常量的記憶體位址,可以使用 enum 的方式定義常量,enum 會幫你約束這個條件,因為取乙個 enum 的位址是不合法的,形式如下:
class
Student
;int
scores
[num
];};
另外乙個常見的 #define 誤用情況是以它實現巨集函式,它不會招致函式呼叫帶來的開銷,但是用 #define 編寫巨集函式容易出錯,如下用巨集定義寫的求最大值的函式:
#define MAX(a, b) ( )
// 求最大值
這般長相的巨集有著太的缺點,比如在下面呼叫例子:
inta=6
,b=5
;int
max=
MAX(a++
,b);std
::cout
< std:: endl ;std ::cout <
endl ;輸出結果(以下結果是錯誤的): 7// 正確的答案是 max 輸出 6 8// 正確的答案是 a 輸出 7 要解發布錯的原因很簡單,我們把 MAX 巨集做簡單替換: intmax=( );// a 被累加了2次! 在上述替換後,可以發現 a 被累加了 2 次。我們可以通過改進 MAX 巨集,來解決這個問題: #define MAX(a, b) () 簡單說明下,上述的 __typeof 可以根據變數的型別來定義乙個相同型別的變數。改進後的 MAX 巨集,輸出的是正確的結果,max 輸出 6,a 輸出 7。 雖然改進的後 MAX 巨集,解決了問題,但是這種巨集的長相就讓人困惑。 用 template inline 的方式,寫出短小的函式: template T>inline Tmax (constT& a,constT& b)max 是乙個真正的函式,它遵循作用域和訪問規則,所以不會出現變數被多次累加的現象。 對於單純常量,最好以 const 物件或 enum 替換 #define; 對於形式函式的巨集,最好改用 inline 函式替換 #define。 5樓:「已登出」 1、如果是完成一些條件編譯的功能,那麼大膽的使用巨集吧。 #if _DEBUG_DENNISTHINK_#else #endif 2、如果是完成一些常量的定義什麼的,那麼更加推薦你使用const 型別的變數和 constexpr 3、在不用巨集可以完成功能的情況下,優先選擇不適用巨集。 個人建議,僅供參考。 6樓:望山 C++有一些機制是用來替代C語言傳統上用巨集實現的功能的,比如const代替#define常數,需要此類功能時就盡量使用它而不是巨集。如果有必要的時候,盡可能以最簡明方式使用巨集,初學者不要濫用巨集,不要玩花樣。 7樓:迅迅 巨集可以用,只是很難用得好 巨集只是乙個工具,就像一把菜刀。你可以用來做菜,也能用來砍人。 該不該用,是看你會不會用的。 巨集需要注意的是: 1.不方便debug 2.會有一些連帶/負面的效果 8樓: 不一定,看情況 比如巨集定義有乙個技巧利用 ## 來拼接編譯時字串, 這個如果用cpp實現,有時候會很麻煩 還有模板乙個問題是錯誤資訊會給一大堆,但是好除錯,debug的時候可以直接斷點進入 總的來說,如果乙個東西用模板寫起來很複雜,建議還是使用巨集 大段長安 沒有必要可以避免吧,除非發現特別不利的影響,比如影響了程式的效率。我不是專業程式設計師,所以一貫在c 中寫入一些c函式的。就從你的舉例來說,printf的可讀性確實要好一些。 SuperFashi 是的,C 使用時除非實在沒有替代品 例如exit函式 否則一定避免使用C。例如不用sprin... 團隊人員不專業。工作室發照維粉都做不到,經紀人在秋月之後接古裝的必須都不懂。拍了部現裝一點水花都沒有,20年唯一一部播劇居然是趕粉的存在。秋月入坑後對於劇粉失望佔大多數,失策至極。秋月後兩個月四本雜誌,時間後零雜誌可見劇粉失望流失。五部待播劇一部都不播。其中主演一部重配兩部,兩部客串可忽略,不是了解... shzy delete指標後立馬賦值nullptr,並不 總 是乙個好習慣。他可能會掩蓋一些錯誤並使你的程式看似良好的繼續執行。因為delete nullptr在c 標準中有明確的定義。C 盡量總在析構裡delete,用raii管理資源。如果你偶然想嘗試delete後置空,八成是因為你無法確定指標接...C 中是否應避免使用C語言函式
李巨集毅為什麼不火?
為什麼C 中在析構函式中使用delete p和在普通函式中用產生不一樣的結果?