天天看點

《嵌入式Linux與物聯網軟體開發——C語言核心深度解析》一2.2 常用位操作符

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

《嵌入式Linux與物聯網軟體開發——C語言核心深度解析》一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 &amp; 5 = 1。

3 &amp;&amp; 5 = ?

分析:3(邏輯真),0(邏輯假),真 &amp;&amp; 假 = 假,是以結果為假,即<code>`</code>javascript

3 &amp;&amp; 0 = 0。

3 &amp;&amp; -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 &lt;&lt; 2 = 20。在這個移位的過程中,我們也發現了一個規律,每進行一次左移位操作,得到的結果是原操作數的一倍(x &lt;&lt; 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 &gt;&gt; 2 = 1。在這個移位的過程中,我們也同樣發現了一個規律,每進行一次右移位操作,得到的結果是原操作數的一半(x &gt;&gt; n = x / 2^n)。