c語言裡的巨集(翻譯)4

2022-02-12 04:07:45 字數 2054 閱讀 2550

巨集引數

function-like巨集可以帶引數,就好像函式帶引數一樣。定乙個乙個帶引數巨集的時候,把引數插入到兩個括號之間,就好像定義函式的引數一樣。這就是該類巨集被稱為function-like巨集的原因。巨集引數必須是合法的c標識,由逗號和空格隔開。

呼叫帶引數的巨集,你可以在寫完巨集名之後插一對括號,然後在括號裡跟實參,由逗號隔開。巨集呼叫的**並不是必須寫在一行裡,你可以想寫多少行就寫多少行。實參的數目必須符號定義時引數的數目。巨集展開時,巨集內容裡的引數會自動被實參內容替代。(並不是所有的引數都必須在巨集內容裡出現。)

舉個例子,這裡有乙個巨集,作用是計算兩個數值中較小的那乙個,c語言的**裡常出現這樣的巨集

#define min(x, y)  ((x) < (y) ? (x) : (y))

x = min(a, b); ==> x = ((a) < (b) ? (a) : (b));

y = min(1, 2); ==> y = ((1) < (2) ? (1) : (2));

z = min(a + 28, *p); ==> z = ((a + 28) < (*p) ? (a + 28) : (*p));

(在這個小巨集裡面,你已經可以看到很多帶引數巨集的危險,詳情請看巨集的陷阱)
起始的和末尾的空格會被慮掉,兩個記號之間的所有空格都會被替換成乙個空格。每個引數間的括號必須配對;括號內的逗號不會結束語句。然而,中括號和大括號則不必配對,並且中括號或大括號內的逗號會被當成是分割兩個引數的記號,所以
macro (array[x = y, x + 1])
解析出了兩個引數:array[x = y, 以及x + 1]。如果你想要的結果是把array[x=y, x+1]整個當成引數,那麼你就得這樣寫:array[(x=y, x+1)]。
所有的巨集引數都在替換到巨集內容之前展開。替換了之後,完整的內容又被掃瞄一遍,以便巨集內容包括引數本身被展開。這條規則看上去很奇怪,但它是仔細設計過的,這麼做的結果就是,你完全不必關心你呼叫的到底是函式還是巨集。實際上如果你想在這點上表現的聰明點,結果反而會很糟。參看引數預掃瞄獲取更多的細節。
舉個例子,min (min (a, b), c)首先被展開成
min (((a) < (b) ? (a) : (b)), (c))
然後展開成
((((a) < (b) ? (a) : (b))) < (c)

? (((a) < (b) ? (a) : (b)))

: (c))

(這裡的分行只是為了看著方便,不是真的會展開成分行的**)
你可以把巨集引數留空,預處理器不會認為這是個錯誤(但是很多巨集會展開成不合法**)。但是你不能完全不管引數。如果乙個巨集帶兩個引數,引數列表的頂層必須只能有乙個逗號
min(, b)        ==> ((   ) < (b) ? (   ) : (b))

min(a, ) ==> ((a ) < ( ) ? (a ) : ( ))

min(,) ==> (( ) < ( ) ? ( ) : ( ))

min((,),) ==> (((,)) < ( ) ? ((,)) : ( ))

min() 錯誤,min巨集要求兩個引數,但這裡只有乙個引數

min(,,)    錯誤,min巨集裡面傳入了3個引數,但實際只需要兩個
空格不是預處理符號,所以如果巨集foo帶乙個引數,foo  ()和foo  (   )都提供給巨集乙個空引數。之前的gnu預處理器對這一點的實現和文件都是錯誤的。
字元常量裡出現的巨集引數名不會展開:
#define foo(x) x, "x"
foo(bar)        ==> bar, "x"

c語言裡的巨集(翻譯)2

object like 巨集 object like巨集是乙個簡單的標識,在編譯器會被一段 代替。由於它看上去很像乙個在 中被使用的資料域,所以管它叫object like巨集。最常使用該型別巨集的場合是 用乙個指定符號代替乙個數字常量。使用 define 指令定義乙個巨集,define之後跟乙個巨...

C語言巨集裡 的用法

c 和c 中的巨集 macro 屬於編譯器預處理的範疇,屬於編譯期概念 而非執行期概念 下面對常遇到的巨集的使用問題做了簡單總結。關於 和 define warn if exp do while 0 那麼實際使用中會出現下面所示的替換過程 warn if divider 0 被替換為 do whil...

c語言裡,關於巨集定義的使用

巨集定義最關鍵的是要注意它只是乙個文字替換,不注意的話,很容易引起歧義,看下面一段 include define m x x x int main int a,b 3 a m b 2 printf d n a return 0 這裡的 m 是想要得到 x 的平方,而在程式中呼叫的引數為 b 2 原本...