關於巨集的一些說明

2021-05-28 05:32:31 字數 2262 閱讀 1989

巨集定義又稱為巨集代換、巨集替換,簡稱「巨集」。 

格式:#define 識別符號 字串

其中的識別符號就是所謂的符號常量,也稱為「巨集名」。 

預處理(預編譯

)工作也叫做巨集展開:將巨集名替換為字串。

掌握「巨集」概念的關鍵是「替換」,一切以替換為前提。(預處理器是先於編譯器執行的)

例: #define pi  3.14

預處理器會把程式中出現的pi全部換成3.14

說明:(1)巨集名一般用大寫;

(2)使用巨集可提高程式的通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。例如:陣列大小常用巨集定義

(3)預處理是在編譯之前的處理,而編譯工作的任務之一就是語法檢查,預處理不做語法檢查;

(4)巨集定義末尾不加分號(新手比較可能犯這種錯誤);

(5)巨集定義寫在函式的花括號外邊,作用域為其後的程式,通常在檔案的最開頭;

(6)可以用#undef命令終止巨集定義的作用域;

(7)巨集定義可以巢狀 ;

(8)字串" "中永遠不包含巨集;

(9)巨集定義

不分配記憶體(只是替換),變數定義分配記憶體。

除了一般的字串替換,還要做引數代換

格式:#define 巨集名(參數列) 字串

例如:#define s(a,b) a*b

area=s(3,2);               //第一步被換為area=a*b; ,第二步被換為area=3*2;

類似於函式呼叫:

(1)實參如果是表示式容易出問題,最好給表示式中的引數都加上" () "

#define s(r) r*r

area=s(a+b);第一步換為area=r*r;,第二步被換為area=a+b*a+b;

正確的巨集定義是#define s(r) ((r)*(r))         (最外圍的 "( )"可以不加)

(2)巨集名和包含引數的括號間不能有空格

(3)巨集替換只作替換,不做計算,不做表示式求解

(4)函式呼叫在編譯後程式執行時進行,並且分配記憶體;巨集替換在編譯前進行,不分配記憶體。

(5)巨集的引數不存在型別,也沒有型別轉換。(型別轉換由編譯器在進行編譯時負責)

(6)函式只有乙個返回值,利用巨集則可以設法得到多個值

(7)巨集展開使源程式變長,函式呼叫不會

(8)巨集展開不佔執行時間,只佔編譯時間,函式呼叫佔執行時間(分配記憶體、保留現場、值傳遞、返回值)

這裡順便補充下inline內聯函式

1.巨集定義使用預處理器實現,沒有引數壓棧,**生成等一系列的操作,因此,效率很高,這是它在c中被使用的乙個主要原因;

2. 這種巨集定義在形式上類似於乙個函式,但在使用它時,僅僅只是做預處理器符號表中的簡單替換,因此它不能進行引數有效性的檢測,也就不能享受c++編譯器嚴格型別檢查的好處,另外它的返回值也不能被強制轉換為可轉換的合適的型別,這樣,它的使用就存在著一系列的隱患和侷限性。 

3. 在c++中引入了類及類的訪問控制,這樣,如果乙個操作或者說乙個表示式涉及到類的保護成員或私有成員,你就不可能使用這種巨集定義來實現(因為無法將this指標放在合適的位置)。

正是基於巨集定義的優缺點,在c++中推出了inline以取代這種表示式形式的巨集定義,它消除了它的缺點,同時又很好地繼承了它的優點。

(1)  有參巨集定義中#的用法

#define str(str) #str

#用於把巨集定義中的引數兩端加上字串的 " "

比如,這裡str(my#name)會被替換成"my#name"

一般由任意字元都可以做形參,但以下情況會出錯:

str())這樣,編譯器不會把「)」當成str()的引數。

str(,)同上,編譯器不會把「,」當成str的引數。

str(a,b)如果實參過多,則編譯器會把多餘的引數捨去。(vc++2008為例)

str((a,b))會被解讀為實參為:(a,b),而不是被解讀為兩個實參,第乙個是(a第二個是b)。

(2) 有參巨集定義中##的用法

#define wide(str) l##str

則會將形參str的前面加上l(即寬字元)

比如:wide("abc")就會被替換成l"abc"

如果有#define fun(a,b) vo##a##b()

那麼fun(id ma,in)會被替換成void main()

(3) 多行巨集定義(用" \ "連線):

#define doit(m,n) for(int i=0;i<(n);++i)\

關於platform driver的一些巨集知識

我在寫platform驅動的時候參考了一些linux已有的platform driver 發現了一些我不知道的知識點在這裡和大家分享一下。一 巨集module platform driver 在platform device.h 中定義 我們繼續追蹤 module driver,在device.h中...

關於ID PHOTO FORMAT的一些說明

新近上傳了乙個老作品 年前的東東,翻硬碟的時候找到的,見 包含兩個程式 乙個是用來製作模版的,可以讓你自己根據不同的 尺寸和證件照大小來作乙個模版 比如 製作乙個 吋大小的證件照模版,只要跑到照相館印一張 吋照,你回家自己就能裁出幾十張證件照 另乙個是用來生成輸出檔案的,可以載入上面那個程式製作好的...

關於 Link Cut Tree 的一些說明

實現 和上次的splay一樣,把你們的independence開起來,今天我們再嗨一次 學習link cut tree需要一定的splay的基礎,如果你的基礎還是像我一樣不夠紮實,上面的鏈結,學習一下sp lay spl ay 再走.這個部落格真是命運多舛.寫完了突然卡了發布不了,然後重新整理一下又...