Linux c中的位運算

2021-06-09 17:34:51 字數 2670 閱讀 8706

所謂的位運算指的是二進位制位的運算。在系統軟體中,常要處理二進位制位的問題。例如,將乙個儲存單元中的二進位制位左移或右移以為,兩個數按位相加等等。

c語言中提供了如表1所列出的位運算子。表1

運算子含義

運算子含義&

按位與~ 取反

| 按位或<<  左移

^ 按位異或

>>  右移

說明:1、位運算中除~以外,均為二目運算子,即要求兩側各有乙個運算量。

2、運算量只能是整型或字元型的資料,不能為實型資料。

下面對各個運算子做簡單的介紹。

按位與運算子

(&)參加運算的兩個資料,按二進位制位進行「與」運算。運算規則為:如果兩個相應的位上的二進位制為都為1,則該位的運算結果也為1,否則為0。即如下的表示式:

0&0=0   0&1=0   1&0=0   1&1=1

如果參加位運算的運算元為負數,則以補碼的形式表示二進位制數,然後按位進行與運算。

按位與運算有一些特殊的用途如下:

1、清零。

如果想將乙個單元清零,即使其全部二進位制位為0,只要找乙個二進位制數,其中各個位符合下面的條件:原來數中為1的位置,新數中相應的位為0,然後使二者進行與運算,既可以達到清零的母的。

2、取乙個數中某些指定的位。只要將要取的某些位與1相與,就可以得到想要取得位的值。

3、將某一位留下來。要想將某一位留下來,就與乙個數進行與運算,次數在該位取1。這一點在嵌入式開發中應用的比較廣泛。例如,在點亮乙個led燈的時候,通過控制與之相連的處理器的io口,取1或者取0 就可以控制led燈的亮和滅。

按位或運算子

( | )

兩個相應的二進位制位中只要有一位為1,該位相或之後的結果就為1。規則如下:

0|0=0   0|1=1   1|0=1   1|1=1

或運算主要是用將乙個資料的某些位置1。

異或運算子

(^)異或運算子^也成為xor運算子。它的規則是:若參加運算的兩個二進位制位同號,則結果為0,異號則為1。即0^0=0,0^1=1,1^0=1,1^1=0。異或的意思就是判斷兩個相應的位值是否為「異」,為「異」就為真,否則為假。

我印象中異或運算的乙個比較有意思的應用是交換兩個值,不使用中間變數。

假設a=3,b=4,想交換a和b的值,可以用下面的賦值語:

a=a^b;

b=b^a;

a=a^b;

上面的三個賦值語句就可以實現交換兩個數的值。

說明:1、執行前兩個賦值語句:「a=a^b和b=b^a」相當於b=b^(a^b)。而b^a^b等於a^b^b。b^b的結果為0,因為同乙個數與本身相異或,結果必為0。因此,b的值就等於a^0,          其值為3。

2、再執行第三個賦值語句:a=a^b。由於a的值的等於(a^b),b的值等於(b^a^b),因此,相當於a=a^b^b^a^b,即a的值等於b的值,即4。 注:

回顧我們所學過的,實現交換兩個數的值的方法有4種。

取反運算子

(~)~是乙個單目運算子,用來對乙個二進位制數按位取反,即將0變為1,將1變0。取反運算子的優先順序比算術運算子,關係運算子,邏輯運算子和其他位運算子都要高。

左移運算子

(<<)

用來將乙個數的各二進位制位全部左移若干位。高位左移溢位後就捨棄。左移1 位相當於該數乘以2,左移兩位就相當於乘以2的平方,依次類推,左移多少位就相當於該數乘以2的多少次方,但是此結論只適用於該數左移時被溢位捨棄的高位中不含1的情況。

右移運算子

(>>)

用於將乙個數的各二進位制位全部右移若干位,移到右端的低位被捨棄,對去符號數,高位補0.右移以為相當於除以2,右移n位相當於除以2的n次方。在右移的過程中,需要注意符號位的問題。對於無符號數,右移時左邊高位補0,對於有符號的值,如果原來符號位為0,則左邊也是一如0;如果符號位為1,,則左邊移入的是1還是0,要取決於所用的計算機系統。移入0的稱為「邏輯右移」,移入1的稱為「算術右移」。

補充知識:位段

位段以位為單位定義的結構體中成員所占用儲存空間的長度,含有位段的結構體型別稱為位段結構。位段結構也是一種結構體型別,只不過其中含有以位為單位定義儲存長度的整數型別位段成員。採用位段結構既節省儲存空間,又可方便操作。

位段結構中位段的定義格式為:unsigned  《成員名》 : 《二進位制位數》 例:

struct bytedata

data;

位段資料的引用:同結構體成員的資料引用一樣,但是應該注意位段的最大值範圍不要超過二進位制位數定的範圍,否則超出部分會丟棄。例如:

data.a=2;

但是data.a=10;

就超出了範圍。

關於位段資料,注意以下幾點: (

1)乙個位段必須儲存在同一儲存單元(即字)之中,不能跨兩個單元。如果其單元空間不夠,則剩餘空間不用,從下乙個單元起存放該位段。(2

)可以通過定義長度為

0的位段的方式使下一位段從下一儲存單元開始。(3

)可以定義無名位段。(4

)位段的長度不能大於儲存單元的長度。(5

)位段無位址,不能對位段進行取位址運算。(6

)位段可以以%d,

%o,%x格式輸出。(7

)位段若出現在表示式中,將被系統自動轉換成整數。

結構體大小原則:由於儲存變數時位址對齊的要求,編譯器在編譯程式時會遵循兩條原則:第

一、結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍)。第

二、結構體大小必須是所有成員大小的整數倍。

linux c按位運算子

按位取反 0變成1,1變成0。按位與 兩邊都為1的為1,其他為0。按位或 只要有一方為1的就為1,其他為0。按位異或 一方為0,一方為1的為1,其他為0 例子 include typedef unsigned char u char void main 下面由例子看一次實際應用場景 include ...

Java 中的位運算

移位運算子 包括 右移 左移 無符號右移 例子 5 3 1 1111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1111 1111 其結果與 math.floor double 5 2 2 2 完全相同。5 3 ...

Java 中的位運算

計算機中的原碼 反碼和補碼 移位運算子 包括 右移 左移 無符號右移 例子 5 3 1 1111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1111 1111 其結果與 math.floor double 5 2...