首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言巨集交換陷阱:為何 a=a+b;b=a-b;a=a-b; 會失效?

     編輯:關於C語言

問題現場

實作全排列時發現兩種 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]))時:

  • 版本 1:a=a+b 讓 a 變 2倍,但 b 同步變化(因為是同一記憶體),導致後續 b=a-b 變 0,最終全歸 0。
  • 版本 2:引入獨立 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
結果:數值歸零,交換失敗。

最佳實踐建議

  1. 優先使用函式而非巨集:型別安全、可除錯、支援內聯最佳化。
  2. 若必須用巨集,採用暫存變數版本,並用 do { ... } while(0) 包裹避免語法陷阱:
#define SWAP(type, a, b) \
    do { type tmp = (a); (a) = (b); (b) = tmp; } while(0)
  1. 陣列元素交換時,檢查索引是否相同,相同則略過交換。

本文轉載自 “實踐心得” 博客,原文出處:https://zhangjiabin.blog.51cto.com/2325830/1288273

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved