所謂位運算,即對二進位制中的單一位元進行操作。位元是電腦儲存資料的最小單位,8 個位元組成一個位元組。C 語言提供六種位運算子,分別為:
| 運算子 | 名稱 | 功能 |
|---|---|---|
| & | 按位與 | 兩位皆為 1 結果才為 1 |
| | | 按位或 | 兩位有一為 1 結果為 1 |
| ^ | 按位異或 | 兩位不同結果為 1 |
| ~ | 取反 | 0 變 1、1 變 0 |
| << | 左移 | 高位捨棄,低位補 0 |
| >> | 右移 | 低位捨棄,高位補符號位 |
只有參與運算的兩個位元都為 1 時,結果才為 1。例如 9 & 5:
0000 0000 0000 0000 0000 0000 0000 1001 (9)
& 0000 0000 0000 0000 0000 0000 0000 0101 (5)
--------------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0001 (1)
結果為 1。負數以補碼形式儲存,-9 & 5 結果為 5。
常見用途: 清零特定位元、保留特定位元。例如 n & 0xFFFF 可保留低 16 位,清零高 16 位。
參與運算的兩個位元有一個為 1 即結果為 1。9 | 5 結果為 13,-9 | 5 結果為 -9。
常見用途: 設定特定位元為 1。例如 n | 0xFFFF0000 將高 16 位設為 1。
兩個位元不同時結果為 1,相同時為 0。9 ^ 5 結果為 12,-9 ^ 5 結果為 -14。
常見用途: 翻轉特定位元。例如 n ^ 0xFFFF0000 翻轉高 16 位。
單目運算子,將每個位元反轉。~9 結果為 -10,~-9 結果為 8。
將位元向左移動指定位數,高位捨棄,低位補 0。9 << 3 結果為 72(相當於乘以 2³)。負數左移同理,(-9) << 3 結果為 -72。
將位元向右移動,低位捨棄,高位補符號位(正數補 0,負數補 1)。9 >> 3 結果為 1,(-9) >> 3 結果為 -2(相當於除以 2³ 並向下取整)。
#include <stdio.h>
int main() {
int n = 0x8FA6002D;
printf("%d, %d, %X\n", 9 & 5, -9 & 5, n & 0xFFFF); // 1, 5, 2D
printf("%d, %d, %X\n", 9 | 5, -9 | 5, n | 0xFFFF0000); // 13, -9, FFFF002D
printf("%d, %d, %X\n", 9 ^ 5, -9 ^ 5, 0x0A07002D ^ 0xFFFF0000); // 12, -14, F5F8002D
printf("%d, %d\n", ~9, ~-9); // -10, 8
printf("%d, %d\n", 9 << 3, (-9) << 3); // 72, -72
printf("%d, %d\n", 9 >> 3, (-9) >> 3); // 1, -2
return 0;
}
位運算是針對記憶體中的二進位補碼表示進行運算,而非數學上的二進位形式。負數在記憶體中以補碼儲存,與其絕對值的二進位形式截然不同,請務必區分。