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

C語言位元運算完全指南:六大運算子、實戰技巧與常見陷阱

     編輯:關於C語言

前言:位元運算——C 語言的「組合語言」面向

C 語言完整支援位元運算,直接操作位元組/字的二進制位。這使 C 能編寫驅動程式、嵌入式固件、壓縮演算法、密碼學等底層代碼。位元運算僅適用於整數型別 (含 char),不適用浮點數。

一、六大位元運算子

運算子名稱功能真值表 (單位位元)
&位元 AND兩位皆 1 結果 10&0=0, 0&1=0, 1&0=0, 1&1=1
|位元 OR任一位為 1 結果 10|0=0, 0|1=1, 1|0=1, 1|1=1
^位元 XOR兩位不同結果 10^0=0, 0^1=1, 1^0=1, 1^1=0
~位元 NOT單目,逐位取反~0=1, ~1=0
<<左移高位捨棄,低位補 0x << n 等價 x * 2^n
>>右移低位捨棄,高位補 0/1有號數實作定義 (算術/邏輯右移)

二、位元運算 vs 邏輯運算:關鍵區別


int x = 7;  // 0111
int y = 8;  // 1000

x && y  // 邏輯 AND:兩者非零 → 1 (真)
x & y   // 位元 AND:0111 & 1000 = 0000 → 0
  • 邏輯運算結果只能是 0 或 1
  • 位元運算結果可為任意整數值
  • 邏輯運算有短路求值;位元運算無短路,兩邊必評估

三、經典實戰技巧

1. 位元遮罩:提取/清除/設定特定位


#define BIT(n) (1u << (n))

// 清除第 3 位 (保留其它)
x &= ~BIT(3);

// 設定第 5 位
x |= BIT(5);

// 切換第 0 位
x ^= BIT(0);

// 測試第 7 位
if (x & BIT(7)) { ... }

// 提取低 8 位
low8 = x & 0xFF;

2. 快速乘除 2 的冪次


x << 3   // x * 8
x >> 2   // x / 4 (無號數/正數)
// 負數右移行為實作定義,嚴謹場合用除法

3. 交換兩變數 (無暫存變數)


a ^= b;
b ^= a;
a ^= b;
// 僅適用整數,現代編譯器優化臨時變數同樣快,可讀性差,教學用

4. 判斷 2 的冪次


bool isPowerOfTwo(unsigned x) {
    return x && !(x & (x - 1));
}
// x=8: 1000 & 0111 = 0 → true
// x=6: 0110 & 0101 = 0100 ≠ 0 → false

5. 奇偶校驗 / 計算 1 的個數 (Population Count)


int popcount(unsigned x) {
    x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
    x = (x * 0x01010101) >> 24;
    return x;
}
// 或使用內建 __builtin_popcount (GCC/Clang)

6. 大小端轉換 (32-bit)


uint32_t swapEndian(uint32_t x) {
    return ((x & 0xFF000000) >> 24) |
           ((x & 0x00FF0000) >> 8)  |
           ((x & 0x0000FF00) << 8)  |
           ((x & 0x000000FF) << 24);
}

四、移位運算深度解析

場景左移 <<右移 >>
無號數低位補 0,高位捨棄高位補 0 (邏輯右移)
有號正數同無號數高位補 0
有號負數同無號數 (未定義行為若溢位)實作定義:多數編譯器算術右移 (補符號位 1)
移位量 ≥ 位寬未定義行為 (C 標準)
移位量 < 0未定義行為

五、常見陷阱

陷阱錯誤代碼問題修正
浮點數用位元運算float f; f & 1;編譯錯誤/未定義轉整數或用 memcpy 重新解讀
有號數左移溢位int x = 1 << 31;未定義行為 (溢位)用無號數 1u << 31
負數右移可移植性int x = -8; x >> 1;結果視編譯器而定明確需求用除法或無號數轉換
優先級陷阱x & 1 == 0解析為 x & (1 == 0) → x & 0加括號 (x & 1) == 0
巨集參數副作用SET_BIT(x++, 3)x++ 執行多次改用 inline 函數

結語

位元運算是 C 語言區別於高階語言的核心特徵。掌握「遮罩提取/設定/清除、快速乘除、2 冪次判斷、popcount、端序轉換」等實戰模式,並嚴守「無號數位元運算、移位量範圍檢查、優先級括號、避免巨集副作用」四大防線,即可在驅動開發、網路協定、圖形處理、密碼學等領域寫出高效、正確的位元級代碼。

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