c 中是否不建議使用巨集,為什麼?

時間 2021-06-01 16:28:23

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語言函式

大段長安 沒有必要可以避免吧,除非發現特別不利的影響,比如影響了程式的效率。我不是專業程式設計師,所以一貫在c 中寫入一些c函式的。就從你的舉例來說,printf的可讀性確實要好一些。 SuperFashi 是的,C 使用時除非實在沒有替代品 例如exit函式 否則一定避免使用C。例如不用sprin...

李巨集毅為什麼不火?

團隊人員不專業。工作室發照維粉都做不到,經紀人在秋月之後接古裝的必須都不懂。拍了部現裝一點水花都沒有,20年唯一一部播劇居然是趕粉的存在。秋月入坑後對於劇粉失望佔大多數,失策至極。秋月後兩個月四本雜誌,時間後零雜誌可見劇粉失望流失。五部待播劇一部都不播。其中主演一部重配兩部,兩部客串可忽略,不是了解...

為什麼C 中在析構函式中使用delete p和在普通函式中用產生不一樣的結果?

shzy delete指標後立馬賦值nullptr,並不 總 是乙個好習慣。他可能會掩蓋一些錯誤並使你的程式看似良好的繼續執行。因為delete nullptr在c 標準中有明確的定義。C 盡量總在析構裡delete,用raii管理資源。如果你偶然想嘗試delete後置空,八成是因為你無法確定指標接...