本節書摘來自異步社群《嵌入式linux與物聯網軟體開發——c語言核心深度解析》一書中的第2章,第2.2節,作者朱有鵬 , 張先鳳,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

位與就是對數的二進制位進行運算。兩個數每個二進制位的運算規則按照如下規則運算。該規則就是其真值表。
& 0 1
0 0 0
1 0 1
從其運算規則(真值表)可以看出,隻有1和1進行與運算的結果是1,其餘的全是0。如果我們将1當做真,0當做假的話,按照與運算的要求,兩個為真才為真,隻要有一個為假就為假。好了,我們看下面一個例子。
分析可知這兩個是十進制數,是以先把這兩個數都轉化為二進制數。
3轉化二進制:0b0011
5轉化二進制:0b0101
将這兩個數的二進制形式按照上面的運算規則進行按位與運算。
将得到的二進制結果0b0001變為十進制,十進制結果為1。
是以可以得出結論:<code>`</code>javascript
3 & 5 = 1。
3 && 5 = ?
分析:3(邏輯真),0(邏輯假),真 && 假 = 假,是以結果為假,即<code>`</code>javascript
3 && 0 = 0。
3 && -5 = ?
對兩個數的二進制位進行或運算,其真值表如下。
| 0 1
0 0 1
1 1 1
從其真值表可以看出,隻有0和0進行或運算的結果是0,其餘的全是1。對于位或運算來說,運算的兩個位,隻要有一個為1結果就為1,否則都為0。如下面這個例子。
将十進制轉化為二進制。
3轉化為二進制:0b0011
5轉化為二進制:0b0101
對這兩個數的二進制形式按照上面的運算規則進行按位或運算。
将二進制結果0b0111轉化為十進制,十進制結果為7。
是以可以得出結論:3 | 5 = 7。
擴充:|(按位或) 和 ||(邏輯或)的差別
||(邏輯或)是将要運算的兩個數都看成一個整體,而這個整體如果是0,則該數被定義成邏輯假(0);如果該數不為0(不管是正的還是負的),則被定義成邏輯真(1)。來看下面這個小例子。
分析:3(邏輯真),5(邏輯真),真 || 真 = 真,是以結果為真,即3 || 5 = 1。
分析:0(邏輯假),0(邏輯假),假 || 假 = 假,是以結果為假,即0 || 0 = 0。
分析:3(邏輯真) -5(邏輯真),真 || 真 = 真,是以結果為真,即3 || -5 = 1。
位取反就是将操作數的二進制位逐個按位取反(1變成0,0變成1),其真值表如下。
從上真值表中不難發現規律,取反後,1變0,0變1,比如下面這個例子。
10轉化為二進制:0b1010
對操作數的二進制形式按位取反。此處為了友善說明,暫時不考慮更高位補齊。實際程式設計位取反時要考慮取反的數的資料類型,然後在高位補足0,這時0會在取反時變為1。
将二進制結果0b0101轉化為十進制,結果為5。
是以可以得出結論:~10 = 5
擴充:~(按位取反) 和 !(非)的差別
!(非)是将操作數看成一個整體,而這個整體如果是0,則該數被定義成邏輯假(0);如果該數不為0(不管是正的還是負的),則被定義成邏輯真(1)。來看幾個小例子。
分析:10(邏輯真) 非真就是假,是以結果為假,即!10 = 0。
分析:0(邏輯假) 非假就是真,是以結果為真,即!0 = 1。
分析:-10(邏輯真) 非真就是假,是以結果為假,即!(-10) = 0。
位異或就是将兩個數的二進制位進行位異或運算。位運算的真值表如下。
從其運算規則(真值表)可以看出,兩個位如果相等,結果為0,不等則結果為1。比如下面的例子。
将二進制結果0b0110轉為十進制,十進制結果為6。
0b0110轉化為十進制:6
是以可以得出結論:3 ^ 5 = 6。
左移位就是将一個操作數的各二進制位全部左移若幹位,左邊移出去的二進制位丢棄,右邊空出的二進制位補0。話不多說,來看個例子。
将十進制化為二進制。
5轉化為二進制:0b00000101
對操作數0b00000101開始進行左移位兩次。
第一次左移位 0b00001010 (10) = 5 * 2
第二次左移位 0b00010100 (20) = 10 * 2
将二進制結果0b00010100轉為十進制,十進制結果為20。
是以可以得出結論:5 << 2 = 20。在這個移位的過程中,我們也發現了一個規律,每進行一次左移位操作,得到的結果是原操作數的一倍(x << n = x * 2^n)。
右移位就是将一個操作數的各二進制位全部右移若幹位,左邊的二進制位補0或者補1(如果操作數是無符号數或有符号正數就補0,如果是有符号負數就補1),右邊的二進制位丢棄。話不多說,來看例子。
-5轉化為二進制:0b11111011
對操作數0b00000101開始進行右移位兩次。
第一次右移位:0b00000010 (2) = 5 / 2 0b11111101 (-3)
第二次右移位:0b00000001 (1) = 2 / 1 0b11111110 (0)
将得出的結果(二進制)還原成十進制形式。
0b00000001轉化為十進制:1
0b11111110轉化為十進制:0 (按照負數解析)
是以可以得出結論:5 >> 2 = 1。在這個移位的過程中,我們也同樣發現了一個規律,每進行一次右移位操作,得到的結果是原操作數的一半(x >> n = x / 2^n)。