C語言中的位元運算符

哈囉,未來的編程巫師們!今天,我們將進入C語言中位元運算符的精彩世界。如果你是編程新手,不用擔心;我將成為你的友好導遊,一步步為你解釋一切。所以,戴上你的學習帽,我們一起深入探險吧!

C - Bitwise Operators

什麼是位元運算符?

在我們開始之前,讓我們先了解位元運算符是什麼。想象一下,你面前有一排開關。位元運算符就像特殊的工具,能夠以有趣的方式控制這些開關——開啟或關閉它們,甚至交換它們的狀態。在計算機世界裡,這些「開關」實際上是構成我們數據的位元(0和1)。

現在,讓我們一一探索每個位元運算符。

C語言中的位元AND運算符(&)

位元AND運算符就像一個挑剔的朋友,只有當兩個輸入都同意時才會說「是」。它比較兩個數字的每個位元,只有當兩個位元都是1時才返回1。否則,它返回0。

讓我們看一個例子:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制
unsigned int b = 13;  // 13 = 0000 1101 二進制

printf("a & b = %d\n", a & b);

return 0;
}

輸出:

a & b = 12

這是怎麼回事?讓我們來解析一下:

0011 1100  (60的二進制)
& 0000 1101  (13的二進制)
----------
0000 1100  (12的十進制)

看到它只在兩個數字都是1的位置保留1嗎?這就是位元AND的魔力!

位元OR(|)運算符

位元OR運算符就像一個慷慨的朋友,只要其中一個輸入同意就會說「是」。如果對應的位元至少有一個是1,它就返回1。

這裡有一個例子:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制
unsigned int b = 13;  // 13 = 0000 1101 二進制

printf("a | b = %d\n", a | b);

return 0;
}

輸出:

a | b = 61

讓我們來解析一下:

0011 1100  (60的二進制)
| 0000 1101  (13的二進制)
----------
0011 1101  (61的十進制)

看到它在哪裡有1就保留1嗎?這就是位元OR!

位元XOR(^)運算符

XOR運算符就像一個喜歡事物不同的古怪朋友。如果位元不同,它返回1;如果相同,則返回0。

讓我們看看它的作用:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制
unsigned int b = 13;  // 13 = 0000 1101 二進制

printf("a ^ b = %d\n", a ^ b);

return 0;
}

輸出:

a ^ b = 49

這是發生了什麼:

0011 1100  (60的二進制)
^ 0000 1101  (13的二進制)
----------
0011 0001  (49的十進制)

XOR經常被用於密碼學,因為它很容易逆轉。如果你用同一個值對一個數字進行兩次XOR,你就會得到原始數字。很酷,對吧?

左移(<<)運算符

左移運算符就像一個向左移動位元的傳送帶。它將每個位元向左移動指定的位置數。

這是它的工作原理:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制

printf("a << 2 = %d\n", a << 2);

return 0;
}

輸出:

a << 2 = 240

讓我們來解析一下:

0011 1100  (60的二進制)
<<2 (向左移動2位)
----------
1111 0000  (240的十進制)

注意到位元向左移動,新的0從右邊填充進來了嗎?此外,向左移動1位等於乘以2。所以,向左移動2位等於乘以4!

右移(>>)運算符

右移運算符就像左移的對立雙胞胎。它將位元向右移動。

讓我們看一個例子:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制

printf("a >> 2 = %d\n", a >> 2);

return 0;
}

輸出:

a >> 2 = 15

這是發生了什麼:

0011 1100  (60的二進制)
>>2 (向右移動2位)
----------
0000 1111  (15的十進制)

位元向右移動,新的0從左邊填充進來。右移動1位等於除以2(忽略餘數)。

1的補數(~)運算符

1的補數運算符就像位元的鏡子。它將每個位元從0翻轉到1,從1翻轉到0。

這是它的工作原理:

#include <stdio.h>

int main() {
unsigned int a = 60;  // 60 = 0011 1100 二進制

printf("~a = %u\n", ~a);

return 0;
}

輸出:

~a = 4294967235

這裡發生了什麼?讓我們來解析一下:

0000 0000 0000 0000 0000 0000 0011 1100  (60的32位二進制)
~(1的補數)
----------------------------------------
1111 1111 1111 1111 1111 1111 1100 0011  (4294967235的十進制)

每個0變成了1,每個1變成了0。結果看起來很大,因為我們使用的是unsigned int,它將所有這些1解釋為一個正數。

結論

就是這樣,各位!我們已經穿越了C語言中位元運算符的土地。這些強大的工具一開始可能會有點棘手,但隨著練習,你會發現它們對於處理硬件、優化代碼甚至一些酷炫的派對技巧(如果你 的派對涉及二進制數學的話)都非常有用。

記住,掌握這些運算符的關鍵是練習。嘗試使用這些運算符編寫你自己的程序。嘗試不同的數字,看看你會得到什麼結果。在你意識到之前,你將能夠輕鬆地進行位元操作!

編程愉快,願位元永遠在你一邊!

運算符 符號 描述
AND & 如果兩個位元都是1,則返回1,否則返回0
OR | 如果至少有一個位元是1,則返回1,否則返回0
XOR ^ 如果位元不同,則返回1,如果相同,則返回0
左移 << 將位元向左移動指定的位置數
右移 >> 將位元向右移動指定的位置數
1的補數 ~ 將所有位元翻轉(0變成1,1變成0)

Credits: Image by storyset