#define f(a,b) a##b // (1)
#define g(a) #a // (2)
#define h(a) g(a) // (3)
例如,有以上三個巨集定義,求下面的結果:
printf("%s\n", g(f(1, 2)));
printf("%s\n", h(f(1, 2)));
注意:巨集定義中的#的意思:巨集定義中#是「字串化」的意思,是把跟在後面的引數轉換成乙個字串,例如#a等同於「a」,#abc等同於「abc」。
巨集定義中的##是
乙個連線符號,用於把引數連在一起。例如,a##b##c等同於abc
計算方法:一、如果巨集定義是帶#的,如(2)所示,則直接替換。g(f(1,2))--->#f(1,2)--->"f(1,2)"
二、如果巨集定義是不帶#的,如(1)、(3)所示,基本原則為展開引數然後替換。步驟為:由外層向里層走,如果碰到的是以非#開頭的巨集,則繼續往裡層走,直到最裡層,然後開始往外層展開。如果碰到的是以#開頭的巨集,則不再往裡層走,往外層展開。h(f(1,2))--->h(12)--->g(12)--->#12--->"12"
如下例子:
char a = 'c';
cout << g(a) << endl; // "a"
cout << g(g(a)) << endl; // "g(a)"
printf("%s\n", h(f(1, 2))); // "12"
printf("%s\n", g(f(1, 2))); // "f(1,2)"
printf("%s\n", g(h(f(1, 2)))); // "h(f(1,2))"
printf("%s\n", h(g(f(1, 2)))); // ""f(1,2)""
printf("%s\n", h(h(f(1, 2)))); // ""12""
巨集解析
1. ##操作符
##操作符它的作用是在替代表中將其前後的引數連線成為乙個預處理符號,它不能出現於巨集替代表的開端和末尾。
例:#define concat(s,t) s##t
#define aaa abc
concat(a, aa)
將被替換成
abc2. 重新掃瞄和替換
在替換列表中的所有引數替換過之後,預處理器將對結果token序列重新掃瞄以便對其中的巨集再次替換。
當正在替換的巨集在其替換列表中發現自身時,就不再對其進行替換。今兒,在任何正在巢狀替換的巨集的替換過程中遇到正被替換的巨集就對其不再進行替換(防止遞迴)。
例:#define root aaa ccc
#define aaa root
root
將被替換成
root ccc
C語言巨集定義中的 , , 及 符號的作用
c語言巨集定義中的 及 符號的作用 1 stringizing 字串化操作符 作用 將巨集定義中的傳入引數名轉換成用一對雙引號括起來引數名字串。其只能用於有傳入引數的巨集定義中,且必須置於巨集定義體中的引數名前。如 define example instr printf the input stri...
C語言巨集定義中的 , , 及 符號的作用
作用 將巨集定義中的傳入引數名轉換成用一對雙引號括起來引數名字串。其只能用於有傳入引數的巨集定義中,且必須置於巨集定義體中的引數名前。如 define example instr printf the input string is t s n instr define example1 instr...
C 和 在巨集定義中的作用
將右邊的引數做整體的字串替換。define string x x x define text x name x inttest 將左右兩邊的引數做整體的字串拼接替換。define class name name class name define merge a,b a b a inttest 對於...