c語言的位操作

2021-09-23 10:33:28 字數 3816 閱讀 8422

c語言的位操作最常用的地方就是用在對暫存器的寫值上。

一.基本的一些概念

1.位與:&

操作:1 & 1 = 1;  1 & 0 = 0;  0 & 0 = 0;

特點:只有全是1的時候才是1,其他情況都是0.

總結:任何數和0位與就是0,和1位與沒有變化,所以位與常用在清零上(清零用位與)。

2.位或:|

操作:1 | 1 = 1;  1 | 0 = 1;  0 | 0 = 0;

特點:只有全0的時候才是0,其他情況都是1.

總結:任何數和1位或就是1,和0位或沒有變化,所以位或常用在置1上(置1用位或)。

3.位取反:~

操作:~1 = 0;  ~0 = 1;

特點:1取反為0,0取反為1.

4.位異或:^

操作:1 ^ 1 = 0;  1 ^ 0 = 1; 0 ^ 1 = 1; 0 ^ 0 = 0;

特點:相同為0,不同為1.

總結:任何數和1位異或會取反,和0異或沒有變化(特定位要取反就用位異或)。

5.左移(<<)和右移(>>)

操作的時候要考慮有符號數(signed number)和無符號數(unsigned number)。

對於有符號數:左移的時候右側補0;右移的時候左側補符號位(正數符號位為0,則補0;負數符號位為1,則補1).

對於無符號數:左移的時候右側補0;右移的時候左側也是補0.

注意:我們對暫存器進行賦值的時候用的都是無符號的數

二.與邏輯運算的區別

1.邏輯運算的基本符號:邏輯與(&&)  邏輯或(||)  邏輯取反(!)

2.我們需要注意的地方就是:位操作中只有1和0;邏輯操作的中非0代表是真(1),0就代表是假(0)

3.運算的時候,位運算是把數字拆為一位一位的進行運算的;邏輯運算是把數字作為乙個整體進行運算的,但是他們運算的基本操作和位運算一致(譬如:1 && 1 = 1, 0 && 1 = 0 等等)。

譬如:7 && 0 = 0    111 & 0 = 0

7 && 3 = 1    111 & 011 = 011

三.對暫存器寫值的三部曲

1.首先,把暫存器中的值讀出來

2.其次,修改暫存器中的值

3.最後,把修改好的值寫進去

四.**實戰

1、給定乙個整型數a,設定a的bit3,保證其他位不變

注意:設定就是設定為1的意思,清除就是清除為0的意思

1 unsigned int a = 0xc3057ad3;

2 a |= (1<<3);

3 printf(「a = 0x%x.\n」, a); //a = 0xc3057adb.

2、給定乙個整形數a,設定a的bit3~bit7,保持其他位不變

1 unsigned int a = 0xc3057ad3;

2 a |= (0x1f<<3);

3 printf(「a = 0x%x.\n」, a); //a = 0xc3057afb.

3、給定乙個整型數a,清除a的bit15,保證其他位不變。

1 unsigned int a = 0xc305bad3;

2 a &= ~(1<<15);

3 printf(「a = 0x%x.\n」, a); //a = 0xc3053ad3.

4、給定乙個整形數a,清除a的bit15~bit23,保持其他位不變。

1 unsigned int a = 0xc305bad3;

2 a &= ~(0x1ff<<15);

3 printf(「a = 0x%x.\n」, a); //a = 0xc3003ad3.

5、給定乙個整形數a,取出a的bit3~bit8。

注意:要取出這個數,首先要把其他位清零&,之後右移就可以得出那個數了

1 unsigned int a = 0xc305bad3;

2 unsigned int tmp;

3 tmp = a & (0x3f<<3);

4 tmp >>= 3;

5 printf(「tmp = 0x%x.\n」, tmp);

6、用c語言給乙個暫存器的bit7~bit17賦值937(其餘位不受影響)。

注意:要賦值就需要把要賦值的那幾位清零&,然後把需要賦值的數左移到那幾位上就可以了

1 unsigned int a = 0xc305bad3;

2 a &= (~(0x7ff<<7));

3 a |= (937<<7);

4 printf(「a = 0x%x.\n」, a); //a = 0xc305d4d3.

7、用c語言將乙個暫存器的bit7~bit17中的值加17(其餘位不受影響)。

注意:要加值,就要把那幾位的數字取出來,然後把那幾位清零&,之後右移,相加,左移,再置1 |

複製**

1 unsigned int a = 0xc305bad3;

2 unsigned int tmp;

3 tmp = a & (0x7ff<<7);

4 a &= (~(0x7ff<<7));

5 tmp >>= 7;

6 tmp += 17;

7 tmp <<= 7;

8 a |= tmp;

9 printf(「a = 0x%x.\n」, a); //a = 0xc305c353

複製**

8、用c語言給乙個暫存器的bit7~bit17賦值937,同時給bit21~bit25賦值17.

注意:同時賦值和乙個個來賦值是一樣的,就是多了幾步而已

unsigned int a = 0xc305bad3;

a &= (~(0x7ff<<7));

a |= (937<<7);

a &= (~(0x1f<<21));

a |= (17<<21);

printf("a = 0x%x.\n", a); //a = 0xc225d4d3.

不同版本

1 unsigned int a = 0xc305bad3;

2 a &= ((~(0x7ff<<7)) & (~(0x1f<<21)));

3 a |= ((937<<7) | (17<<21));

4 printf(「a = 0x%x.\n」, a); //a = 0xc225d4d3.

五.用巨集定義來實現位操作

1.其實目的就是把幾行的**寫到一行去(難度也是在這裡),我們直接看**,自己領悟。

按 ctrl+c 複製**

#include

//這裡就是要把數字x的第n位(bit(n-1)位)置為1

//1u就表示的是無符號的1,巨集定義可以傳參的

#define set_bit(x,n) (x | 1u<<(n-1))

//這裡就是要把數字x的第n位(bit(n-1)位)清零

#define clear_bit(x,n) (x & ~(1u<<(n-1)))

//這裡就是要把數字x的第n到m位置為1(n是低位,m是高位)

//就是先把0取反就可以得到很多的1,然後左移就得到那麼多個0,再取反就可以得到你想要的1的個數了

//最後左移位或就可以置1了

#define set_bits(x,n,m) (x | (0u<<(m-n+1))<<(n-1))

//擷取變數的部分連續位。(就是取出的意思)

//其實和上面那裡是差不多的,後面那一大部分都是為了確定需要多少個1

//最後記得右移,為了得出那個數字

#define get_bit(x,n,m) (x & (0u<<(m-n+1))<<(n-1)) >>(n-1)

int main (void)

按 ctrl+c 複製**

C語言位操作

在電腦程式中,資料的位是可以操作的最小資料單位,理論上可以用 位運算 來 完成所有的運算和操作。一般的位操作是用來控制硬體的,或者做資料變換使用,但是,靈活的位操作可以有效地提高程式執行的效率。c語言提供了位運算的功 能,這使得c語言也能像組合語言一樣用來編寫系統程式。位運算子c語言提供了六種位運算...

c語言位操作

位運算 and與 有一位為0 運算就為0 想獲取高四位,a a 0xf0 簡寫 a 0xf0 清零 一三五七位清零 a a 0x55 檢測位 檢測第三位 a a 0x04 遮蔽高四位,保留低4 位 a a 0x0f 統計2進製a中1的個數 1 include2 int main 3 11 print...

C語言位操作

朱老師物聯網大講堂 學習筆記 1 位與 只有1 1才是1,其餘全是0,位或 只有0 0才是0,其餘全是1,位取反 按位操作,位異或 1 0 1 0 1 1,也就是說相異結果是1,與1異或會取反,與0異或無變化,移位分 左 右 移,物件分 有 無符號數,只說一點 有符號數右移左側補符號位,叫算術移位,...