#define swap(t, x, y) \
do { \
t safe ## x ## y; \
safe ## x ## y = x; \
x = y; \
y = safe ## x ## y; \
} while (0)
代碼交換類型爲t的參數x和y。這個C宏是什麼意思?
#define swap(t, x, y) \
do { \
t safe ## x ## y; \
safe ## x ## y = x; \
x = y; \
y = safe ## x ## y; \
} while (0)
代碼交換類型爲t的參數x和y。這個C宏是什麼意思?
##(雙數號符號)運算符在宏定義中給出的宏調用(文本和/或參數)中連接兩個令牌。 Read More
雙磅符號##
用於令牌串聯。
這就是您的代碼在沒有磅密鑰的情況下的樣子。
#define swap(t, x, y) \
do { \
t safexy; \
safexy = x; \
x = y; \
y = safexy; \
} while (0)
您需要通過以下規則遵守使用##
##
操作時,不能在宏定義的 更換列表中的第一個或最後一個項目。##
運算符前面的項目的最後一個令牌是 與##
運算符後面的項目的第一個令牌級聯。串聯發生在參數中的任何宏被擴展爲 之前。如果級聯結果的名稱是有效的宏 ,則即使它在通常不可用的上下文中出現,也可用於進一步替換,即使它出現在 。
如果多於一個操作員##
和/或操作者#
出現在宏定義的 替換列表, 的運算符的計算的順序沒有限定。
欲瞭解更多瞭解read here。
當你調用這個宏,例如像這樣:
swap(double, a, b);
它就會通過內嵌代碼替換掉兩個值,即:
do {
double safeab;
safeab = a;
a = b;
b = safeab;
} while (0);
注意事項:
typeof(a)
,但這不是標準的,因此不便於使用。)##
交換的變量的名稱組成。此運算符僅在宏體中可用,並通過將相鄰的令牌粘貼在一起來創建新令牌。請注意,如果其中一個交換操作數是複合的,則名稱創建失敗,例如, a[i]
或p->x
。通過並置創建名稱有點過分謹慎。因爲交換髮生在它自己的範圍內,所以影子變量是安全的,當然這些變量除外。只需在常規命名約定之外選擇一個名字並跨越你的手指。do { ... } while (0)
包裝是使宏表現像功能的常用方法,如果它們被用作if
或while
主體的唯一表達式,則它是非常重要的。鑑於宏不適用於複合表達式,您不會購買太多。它也不是泛型類型的,因爲當你調用宏時,類型必須是已知的。編寫一個用於交換的小靜態函數;在我看來這更清晰。
C FAQ對type-generic swap宏也有疑問和強烈的意見。
由於你不能交換複合表達式無論如何,我不確定'給定'條款是否真的適用。你只能交換......嗯,我估計,l值。 –
@JonathanLeffler:嗯,你可以交換,比如'a [i]'和'a [j]'或'p-> x'和'p-> y',不是嗎?這不會連接成一個有效的變量名稱,也不是一個「簡單的」單標記表達式。也許「複合表達」不是一個好詞;我在這裏使用了「複合」,因爲它在「複合文字」中使用,即指複合數據類型。 –
順便說一下,我也不確定這個問題完全是關於'##'操作符的,因爲這裏的每個人似乎都假設。原始的,確切地說模糊的問題標題是「這個代碼是如何工作的?」。 –
你得到了什麼輸出? – tharif
雙磅符號##用於標記串聯。 Google for same –
爲了保持以下關於C宏的未寫(?)規則,我建議你在所有CAPS中命名你的宏......'#define SWAP(t,x,y)' – pmg