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

C 語言位運算、邏輯短路、移位技巧與無第三變數交換實戰

     編輯:關於C語言

位運算是嵌入式與系統程式設計的核心技能。本文系統整理位運算與邏輯運算的關鍵特性(短路求值、移位等價乘除、位元組合技巧),並展示三種無需第三變數交換兩數的經典演算法,最後解析緩衝區刷新與有號/無號比較陷阱。

邏輯運算短路特性

&&||
運算子短路規則口訣
左運算元為假(0),右運算元不執行一假則假
左運算元為真(非0),右運算元不執行一真則真
int a = 7, b = 9, c = 0;
printf("%d\n", a > b && c++);  // 0,c 不遞增
printf("%d\n", c);             // 0
printf("%d\n", a < b || c++);  // 1,c 不遞增
printf("%d\n", c);             // 0

移位運算核心規則

  • 左移 << n ≡ 乘以 2^n(溢位截斷)
  • 右移 >> n ≡ 除以 2^n(有號算術右移補符號位,無號邏輯右移補 0)
  • 僅限整數型別,浮點數不可移位。

實戰:暫存器位元操作模式

場景:將 32 位暫存器 reg 的第 15~12 位設為 0101(二進位)。

unsigned int reg = 0xFFFF7FFF;

// 1. 先清零目標位:建立遮罩 1111 << 12 = 0xF000,取反後 AND
reg = reg & ~(15 << 12);        // 清除 bit 12-15

// 2. 再寫入目標值:0101 = 5,左移 12 位後 OR
reg = reg | (5 << 12);          // 設定 bit 12-15 = 0101

// 合寫一行(注意運算子優先序)
reg = (reg & ~(15 << 12)) | (5 << 12);

通用模式:(reg & ~(mask << pos)) | (value << pos)

無第三變數交換三種寫法

方法程式碼優缺點
加減法a = a + b - (b = a);可能溢位,序列點陷阱
XOR 交換a ^= b; b ^= a; a ^= b;無溢位風險,但同位址會歸零
複合賦值a += b -= a = b; (未定義行為)❌ 避免使用

推薦:現代編譯器優化極佳,直接寫 std::swap(a, b) 或 int t=a; a=b; b=t; 最清晰安全。

getchar() 與換行符陷阱

int d = getchar();  // 輸入 'A' + Enter
int c = getchar();  // 直接讀到 '\n' (ASCII 10)
  • Windows 文字模式:\r\n 兩字元;二進位模式:\n。
  • Linux/Unix:統一 \n,無轉換。
  • 解決:讀取字元後呼叫 getchar() 吃掉換行,或用 scanf(" %c", &ch)(前置空白跳過換行)。

輸出緩衝區與 \n/\t 差異

  • \n:換行 + 刷新標準輸出緩衝區(行緩衝模式)。
  • \t、 等:不刷新,資料留在緩衝區,直到 \n、fflush(stdout)、程式結束或緩衝區滿。
printf("Hello World!\n");      // 立即顯示
printf("Welcome\t");           // 不顯示
sleep(3);
printf("Test!!!\t");           // 3 秒後一次性顯示 "Welcome Test!!!"

有號/無號比較陷阱


unsigned int a = 10;
int b = -30;
if (a < b)  // a 隱式轉為無號大數,條件為真!輸出 "a < b"

規則:混合比較時,有號隱式轉換為無號。-30 變為 4294967266,遠大於 10。

避坑:強制轉型 if ((int)a < b) 或統一使用有號型別。

sizeof 比較陷阱


if (sizeof(char) - sizeof(int) > 0)  // sizeof 回傳 size_t (無號),結果為巨大正數
if (sizeof(char) > sizeof(int))      // 正確:直接比較兩個 size_t

總結

  • 短路求值可用於防護性檢查(p && p->foo())。
  • 位元操作採用「清零→寫入」兩步驟,避免影響無關位。
  • 無第三變數交換屬技巧展示,工程上優先可讀性。
  • 緩衝區行緩衝特性導致 \t 輸出延遲,需主動 fflush。
  • 有號/無號混合比較、sizeof 無號特性是 C 語言高頻 Bug 來源,務必建立型別敏感度。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved