C C 位操作 位運算

2021-10-20 22:39:18 字數 4073 閱讀 8224

在c語言中,可以單獨操控變數的位(bit),一般高階語言不會處理這級別的細節,c在提供高階語言便利的同時,還能為組合語言所保留的級別上工作,這使其成為編寫裝置驅動程式和嵌入式**的首選語言。

目錄

二進位制整數(binary)

有符號整數

八進位制(octal)

十六進製制(hex)

位運算子

按位與&的用途:

(1)清零

(2)取乙個數中某些指定位

(3)保留指定位:

「按位或」運算子(|)

「異或」運算子(^)

(1)使特定位翻轉

(2)與0相「異或」,保留原值 

(3)交換兩個值,不用臨時變數

「取反」運算子(~)

左移運算子(<<)

右移運算子(>>)

通常,1位元組包含8位,c語言用**位元組**(byte)表示儲存系統字符集所需的大小,從左往右,分別給這8位分別編號7~0,在一位元組中,編號是7的位被稱為高階位,編號為0的位被稱為低階位。該位元組能表達的最大數字:1111 1111,為255,最小值為:0000 0000,為0,所以一位元組可儲存0~255範圍內的數字,總共256個值。或者通過不同的方式解釋位組合,程式可以用1位元組儲存 -128 ~ +127範圍內的整數,總共還是256個值。

通常,unsigned char用一位元組標識的範圍是0~255,而signed char表示的範圍是 -128 ~ +127.

如何表示有符號整數取決於硬體本身,而不是c語言。一般有三種方式:

-符號量表示法:用一位儲存符號,剩下的7位表示數字本身。如1000 0001表示-1,0000 0001表示+1。其表示範圍是-127 ~ +127,但是有兩個0:-0和+0,容易混淆。

-二進位制補碼:最常用,高階位為0則是正,為1則為負。正數的表示和符號量表示法一樣,負數則是正數的反碼+1.如+127為0111 1111,則負數的二進位制補碼為:1000 0001。負數128為1000 0000。正數為0000 0001,-1則表示為1111 1111.該方法可以表示-128至+127.

-二進位制反碼: 通過反轉位組合中的每一位形成乙個負數。如0000 0001表示1,則1111 1110表示-1,只有乙個-0:1111 1111.該方法能表示-127至+127 。

每乙個八進位制位對應3個二進位制位。

如八進位制 0377,二進位制表示為000 011 111 111

八進位制123,二進位制表示為001 010 011。

每個十六進製制數用四個二位數表示。

如0xf3,二進位制為1111 0011

0xb9,二進位制為1011 1001 。

c++ 提供了按位與(&)、按位或(| )、按位異或(^)、取反(~)、左移(<<)、右移(>>)這 6 種位運算子。  這些運算子只能用於整型運算元,即只能用於帶符號或無符號的型別。

運算子作用示例&

按位與兩個運算元同時為1結果為1,只要有乙個為0,結果為0

|按位或

兩個運算元只要有乙個為1,結果就為1

~按位非

運算元為1,結果為0;運算元為0,結果為1

^按位異或

兩個運算元相同,結果為0;不相同結果為1

<<

左移右側空位補0,左側溢位捨棄

>>

右移右端溢位捨棄,對於無符號數,高位補0。對於有符號數,某些機器將對左邊空出的部分用符號位填補(即「算術移位」)

若想對乙個儲存單元清零,即使其全部二進位制位為0,只要找乙個二進位制數,其中各個位符合一下條件:

原來的數中為1的位,新數中相應位為0。然後使二者進行&運算,即可達到清零目的。

例:

原數為43,即00101011(43),另找乙個數,設它為148,即  10010100(148),將兩者按位與運算:

若有乙個整數a(2byte),想要取其中的低位元組,只需要將a與8個1按位與即可。

a 00101100 10101100

b 00000000 11111111

c 00000000 10101100

與乙個數進行「按位與」運算,此數在該位取1。

例如:有一數84,即01010100(84),想把其中從左邊算起的第3,4,5,7,8位保留下來,運算如下:

a=84,b=59

c=a&b=16

兩個相應的二進位制位中只要有乙個為1,該位的結果值為1。

--規則是:若參加運算的兩個二進位制位值相同則為0,否則為1,即0^0=0,0^1=1,1^0=1, 1^1=0。

應用:

設有數01111010(2),想使其低4位翻轉,即1變0,0變1.可以將其與00001111(2)進行「異或」運算,即:

運算結果的低4位正好是原數低4位的翻轉。可見,要使哪幾位翻轉就將與其進行∧運算的該幾位置為1即可。

因為原數中的1與0進行異或運算得1,0^0得0,故保留原數。

例如:a=3,即 0011(2);b=4,即0100(2)。

想將a和b的值互換,可以用以下賦值語句實現:

a=a^b;

b=b^a;

a=a^b;

a=a^b; // 111 = 011 ^ 100

b=b^a;  // 011= 100 ^ 111

a=a^b; // 100= 111^ 011

它是一元運算子,用於求整數的二進位制反碼,即分別將運算元各二進位制位上的1變為0,0變為1。例如:~77(8)  

左移運算子是用來將乙個數的各二進位制位左移若干位,移動的位數由右運算元指定(右運算元必須是非負值),其右邊空出的位用0填補,高位左移溢位則捨棄該高位

--例如:將a的二進位制數左移2位,右邊空出的位補0,左邊溢位的位捨棄。若a=15,即00001111,左移2位得00111100(60=15*4)。

左移1位相當於該數乘以2,左移2位相當於該數乘以2*2=4,15 << 2=60,即乘了4 。但此結論只適用於該數左移時被溢位捨棄的高位中不包含1的情況。

假設以乙個位元組(8位)存乙個整數,若a為無符號整型變數,則a=64時,左移一位時溢位的是0,而左移2位時,溢位的高位中包含1。

右移運算子是用來將乙個數的各二進位制位右移若干位,移動的位數由右運算元指定(右運算元必須是非負值),移到右端的低位被捨棄,對於無符號數,高位補0。對於有符號數,某些機器將對左邊空出的部分用符號位填補(即「算術移位」),而另一些機器則對左邊空出的部分用0填補(即「邏輯移位」)。

--注意:

對無符號數,右移時左邊高位移入0;對於有符號的值,如果原來符號位為0(該數為正),則左邊也是移入0。如果符號位原來為1(即負數),則左邊移入0還是1,要取決於所用的計算機系統。有的系統移入0,有的系統移入1。移入0的稱為「邏輯移位」,即簡單移位;移入1的稱為「算術移位」。

--例:a的值是八進位制數113755,

a:1001011111101101 (用二進位制形式表示)

a>>1: 0100101111110110 (邏輯右移時)

a>>1: 1100101111110110 (算術右移時)

在有些系統中,a>>1得八進位制數045766,而在另一些系統上可能得到的是145766。turbo c和其他一些c編譯採用的是算術右移,即對有符號數右移時,如果符號位原來為1,左面移入高位的是1。

右移一位相當於除以2

int add(int a,int b)

return a;

}

思路:

int add(int a,int b)

return a;

}int substraction(int a,int b)

參考鏈結

不使用「+」,「-」,「×」,「÷」實現四則運算

c c 位操作 移位運算

在px4中進場可以看到 define mask use gps 1 0 bool not using gps params.fusion mode mask use gps control status.flags.gps 所以我們需要知道這個 1 0 到底是多少,且 是啥,咋運算出來的 1 0 1...

C C 常見位運算

左移運算子 右移運算子 無符號右移運算子 按位與 按位或 按位非 按位異或,相同位為0,不相同為1 判斷x是奇數還是偶數 x 1 0 x乘以乙個2的n次方的數 x n 消去x最後一位的1 x x 1 求x的相反數 x 1 或者 x 1 x的異或操作 x x 1 把x從右邊數第n位變1 x 1 n 1...

c c 位運算妙用

在vc 程式設計中,會發現微軟的很多api裡面都用到了位運算,比如這個函式 createwindowexa in dword dwexstyle,in opt lpcstr lpclassname,in opt lpcstr lpwindowname,in dword dwstyle,in intx...