轉載的文章:
地址:http://www.cnblogs.com/qkhhxkj/archive/2011/06/29/2093894.html
12 位運算
C語言是爲描述系統設計的,因此它應該具有彙編語言所以完成的一些功能。C語言既有高級語言的特點,又具有低級語言的功能。因而具有廣泛的用途和很強的生命力。
12.1 位運算符和位運算
運算符 含義
& 按位與
| 按位或
^ 按位異或
~ 取反
<< 左移
右移
說明:
(1)位運算符中除 ~ 外,均爲二目運算符,即要求出側各有一個運算量。
(2)運算早只能是整型或字符型的數據,不能爲實型數據。
12.1.1 按位與運算符 &
參加運算的兩個數制,按二進制進行 與運算。如果兩個相應的二進位數爲1,剛該位的結果爲 1 否則爲 0 即:
0 & 0 = 0;0 & 1 = 0;1 & 0 = 0;1& 1 = 1
例如:3 & 8 並不等於8,應該是按位與
3 = 00000011
5 = 00000101 &
00000001
因此 3 & 5 的值得 1, 如果參加 & 是負數(-3 & -5),則以補碼形式表示爲二進制數。然後按位進行 與 運算。
按拉與有一些特殊的用途:
(1)清零。如果想將一個單元清零,即使其全部二進位爲 0,只要找一個二進制數,其中各個位符合以下條件:原來數中爲 1 的位,新數中相應位爲 0。然後使二者進行 & 運算,即可以達到清零目的。
(2)取一個數中某些指定位。如有一個整數 a (2個字節)想要其中的低字節。只需將 a 與(337)。按位與即可。
(3)要想將哪一個保留下來,就與一個數進行 & 運算,此數在該位位1,如有一個數 01010100,想把其中左面第3,4,5,7,8可以這樣運算:
01010100
00111011 &
00010000
12.1.2 按位或運算符 |
兩個相應的二進位中只要有一個爲 1,該位的結果就爲 1。
0|0=0; 0|1=1; 1|0=1; 1|1=1;
按位或運算常用來對一個數據的某些位定值爲1,如 a 是一個整數(16位)有表達式 a & 0377,則低 8 位全置爲 1。高 8 位保留原樣。
12.1.3 異或運算符 ^
異或運算符 ^ 也稱 XOR 運算符。它的規則是若參加運算的兩個二進位同號,則結果爲0,異號則爲1。即 0^0=0; 0^1=1; 1^0=1;1^1=0;
下面舉例說明 ^ 運算符的應用。
(1)使特定位翻轉
假設有 01111010,想使其低4 位翻轉,即 1 變爲 0,0 變爲 1,可以將它與 00001111進行 ^ 運算,即
01111010
00001111 ^
01110101
結果值的低 4 位正好是原數低4位的翻轉。
(2)與 0 相 ^ 保留原值
如 012 ^ 00 = 012
00001010
00000000 ^
00001010
因爲原數中的 1 與 0 進行 ^ 運算得 1,0 與 1 運算得 0,故保留原數。
(3)交換兩個值,不用臨時變量
假如 a = 3, b = 4。想將 a 和 b 的值互換,可以用以下賦值語句實現:
a = a ^ b;
b = b ^ a;
a = a ^ b;
a = 011
b = 100 //a = a ^ b;
a = 111//a = 7
b = 100 //b = b ^ a;
b = 011// b = 3
a = 111//a = a ^ b;
a = 100 // 4
12.1.4 取反運算符 ~
~是一個頭單目運算符,用來對一個二進制按位取反,即將 0 變 1,1變 0。例如~25 是對八進制數 25 (即 00010101)按位取反。
00000000 00010101
11111111 11101010 ~
~運算符的優先級別比算術運算符,關係運算符,邏輯運算符和其它運算符都高,例如:~a & b,先進行 ~a 然後進行 & 運算。
12.1.5 左移運算符 <<
用來將一個數各二進位全部左移若干位。例如:
a = a << 2;
將 a 的二進制數左移 2 位,右補 0,若 a = 15,即二進制數 00001111,左移2位得到 00111100,即十進制數60.
高位左移後溢出,捨棄不起作用。
左移一位相當於該數乘以2。但些結論只適用於該數左移時被溢出捨棄的高位中不包含1 的情況。
左移比乘法運算快得多,有些C編譯程序自動將乘2的運算用左移來實現。
12.1.6 右移運算符 >>
a >> 2 表示將 a 的各二進位右移 2 位。移到右端的低位被捨棄,對無符號數,高位補 0。如 a = 017 時:
a = 00001111 >> 2
00000011
右移一位相當於除以 2 ,右移 n 位相當於除於 2^n。
在右移時,需要注意符號位問題。對無符號數,右移時左邊高位移入 0。對於有符號的值,如果原來符號位爲 0 (該數爲正),則左邊也是移入 0,如果上例表示的那樣,如果符號位原來爲 1(該數爲負),則左邊移入的 0 還是 1 ,要取決於所用的計算機系統。移入 0 稱爲 邏輯右移,即簡單右移。移入 1 稱爲 算術右移。
12.1.7 位運算賦值運算符
位運算符與賦值運算符可以組成複合賦值運算符。
如:&=, |=, >>|, <<=, ^=
12.1.8 不同長度的數據進行位運算
如果兩個數據長度不同(例如 long 型和 int 型)進行位運算時(如 a & b 而 a 爲 long型,b 爲 int 型),系統會將二者按右端對齊。如果 b 爲正數,則左側 16 位補滿 0。若 b 爲負數,左端應補滿 1。如果 b 爲無符號整數型,則左側補滿 0。
12.2 位運算舉例
取一個整數 a 從右端開始的 4~7 位
(1)先使 a 右移 4 位
a >> 4;
(2)設置一個低 4 位全爲 1 ,其餘全爲 0 的數,可以用下面方法實現:
~(~0<<4)
~0 的全部二進制爲 1 ,左移 4 位,這樣右端低 4 位爲 0。
(3)將上面二者進行 & 運算。
a >> 4 & ~(~0<<4)