實作全排列時發現兩種 swap 巨集行為不一致:
// 版本 1:算術交換(無需暫存變數)
#define swap(a,b) {a=a+b; b=a-b; a=a-b;}
// 版本 2:暫存變數交換
#define swap(a,b) {tmp=a; a=b; b=tmp;}
版本 1 輸出 2 1、1 2(正確),版本 2 輸出 2 1、1 0(錯誤)。
當傳入參數為同一個變數(如 swap(arr[1], arr[1]))時:
a=a+b 讓 a 變 2倍,但 b 同步變化(因為是同一記憶體),導致後續 b=a-b 變 0,最終全歸 0。tmp,先備份原值,再賦值,不受同一變數影響。假設 a[1] = 2,呼叫 swap(a[1], a[1]): 版本 1 步驟: a = a + b → a=4, b=4 (同一記憶體) b = a - b → b=0 a = a - b → a=0 結果:數值歸零,交換失敗。
do { ... } while(0) 包裹避免語法陷阱:#define SWAP(type, a, b) \
do { type tmp = (a); (a) = (b); (b) = tmp; } while(0)
本文轉載自 “實踐心得” 博客,原文出處:https://zhangjiabin.blog.51cto.com/2325830/1288273