日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

C语言再学习 -- 位操作

發布時間:2025/3/15 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 位操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、二進制

二進制是計算技術中廣泛采用的一種數制。二進制數據是用0和1兩個數碼來表示的數。它的基數為2,進位規則是“逢二進一”,借位規則是“借一當二”,由18世紀德國數理哲學大師萊布尼茲發現。

位:"位(bit)"是電子計算機中最小的數據單位。每一位的狀態只能是0或1。
字節:8個二進制位構成1個"字節(Byte)",它是存儲空間的基本計量單位。1個字節可以儲存1個英文字母或者半個漢字,換句話說,1個漢字占據2個字節的存儲空間。
字:"字"由若干個字節構成,字的位數叫做字長,不同檔次的機器有不同的字長。例如一臺8位機,它的1個字就等于1個字節,字長為8位。如果是一臺16位機,那么,它的1個字就由2個字節構成,字長為16位。字是計算機進行數據處理和運算的單位。?
二進制沒有占位符

二進制1011表示:

1x2^3 + 0x2^2 + 1x2^1 + 1x2^0 = 11


-5 ?二進制為 1111 1011 ? ? ? ? ? ?十進制數之間轉二進制 關系是 ?取反加一
5的 ?二進制 ? 0000 0101
取反 ? ? ? ? ?1111 1010
加一 ? ? ? ? ?1111 1011

有符號整數參看:C語言再學習 -- 負數

二進制浮點數參看:C語言再學習 -- 浮點數


二、八進制

把二進制從右向左每三個數位分成一組,每一組單獨轉換成十進制結果一定在0到7之間。把所有組的轉換結果按順序書寫就得到數字的八進制表示方式。

例如,八進制數451(在C中寫為0451)表示:

4x8^2 + 5x8^1 + 1x8^0 = 297

可以在程序中用八進制方式表示數字必須以0作為開頭,采用%o作為占位符可以把一個整數的八進制表示方式打印在屏幕上


三、十六進制

把二進制數字從右向左每四個數位分成一組,每組單獨轉換成十進制一定在0到15之間,如果轉換結果在10到15之間用英文字母a到f分別表示,把所有轉換結果按順序書寫就得到數字的十六進制表示方式
例 0110 1010 轉換成十六進制為 6a ?
例 0010 1011 ?43 ?053 ? 2b

在程序中使用十六進制方式表示數字,必須以0x開頭,采用%x或者%X作為占位符可以把數字的十六進制表示方式打印在屏幕,上打印結果中不包含0x。
%x做占位符的時候打印結果中的英文字母都是小寫的
%X做占位符的時候打印結果中的英文字母都是大寫的

//占位符 #include <stdio.h> int main() {printf("0%o %d\n",0152,0152); //八進制 記得前面加個 0printf("0x%X 0x%x 0%o %d\n",0xcb,0xcb,0xcb,0xcb); // 十六進制記得前面加 0xreturn 0; } 輸出結果: 0152 106 0xCB 0xcb 0313 203

參看:C語言再學習 -- printf、scanf占位符


參看:二進制轉換對照表

擴展:進制轉換器

1、整數部分的二進制轉換成十進制。

指數十進制數二進制數
2010001
2120010
2240100
2381000
24160001 0000
25320010 0000
26640100 0000
271281000 0000
282560001 0000 0000
295120010 0000 0000
21010240100 0000 0000
21120481000 0000 0000
21240960001 0000 0000 0000
21381920010 0000 0000 0000
214163840100 0000 0000 0000
215327681000 0000 0000 0000
216655360001 0000 0000 0000 0000

2、小數部分的二進制轉換成十進制。

記到小數點后六位就夠了,如果再向后,你可以繼續除2,不過這題目可就有些變態了。

指數?分數二進制十進制
?2-1?1/21?.1?.5
?2-2?1/22?.01?.25
?2-3?1/23?.001?.125
?2-4?1/24?.0001?.0625




??2-5?1/25?.0000 1?.03125
??2-6?1/26?.0000 01?.015625

3、二進制(B,Binary),八進制(O,Octal) 十進制(D,Decimalist),十六進制(H,Hex)

二進制八進制十進制十六進制
0000000
0001111
0010222
0011333
0100444
0101555
0110666
0111777
10001088
10011199
10101210A
10111311B
11001412C
11011513D
11101614E
11111715F

四、位運算符

1、二進制反碼或按位取反:~

需要確認該值是否為unsigned類型,如果是有符號則,正數為原來的數取反、加1

例如:~6?

0000 0110

1111 1001 =473 = -0000 0111 ==-7


2、&(按位與)(串聯)

只有對應數位上都是1的時候結果才是1
3 二進制 ? ? ? 0000 0011 ? ?
5 二進制 ? ? ? 0000 0101
按位與 ?& 為 0000 0001
結果是 1

C也有一個組合的位與賦值運算符:&=。下面兩個語句產生相同的最后結果:

val &= 0377; val = val & 0377


3、|(按位或)(并聯)

只要對應數位中有1則結果就是1

3 二進制 ? ? ?0000 0011 ??
5 二進制 ? ? ?0000 0101
按位或 ?| ?為 0000 0111
結果為 7

C也有一個組合的位或賦值運算符:|=。下面兩個語句產生相同的最后結果:

val 1= 0377; val = val | 0377


4、^(按位異或)

如果對應數位內容一樣則結果是0,否則結果為1

3 二進制 ? ? ? 0000 0011 ??
5 二進制 ? ? ? 0000 0101
按異或 ?^ 為 0000 0110
結果位 6

C也有一個組合的位異或賦值運算符:^=。下面兩個語句產生相同的最后結果:

val ^= 0377; val = val ^0377


5、移位運算符

移動操作符可以把數字中每個二進制數位統一想左或者向右移動n個位置,移動操作會得到一個新數字,不會修改原來的數字。

1) <<表示向左移動操作

向左移動是右邊空出來的位置上一定補充0
例如 二進制 ?(0000 0011) << 2 ?向左移動兩位結果為 ?0000 1100
3 ? ?0000 0011 ? ? 3 x 2^2 =12
? ? ? 0000 1100

再如:

-5 << 2 = -20

也可以這么理解,向左移動n位相當于乘以2的n次方。


2) >>表示向右移動操作

對于unsigned類型,右移時使用0填充左端空出的位。對于有符號類型,結果依賴于機器。空出的位可能用0填充,或者使用符號(最左端的)位的副本填充。

例如 二進制 (0000 1100) >> 2 向右移動兩位結果為 0000 0011

12 ? ?0000 1100 ? ? ? 12 / 2^2 = 3

? ? ? ? ?0000 0011

也可以這么理解,相對于unsigned類型而言向右移動n位相當于除以2的n次方


注意:

應避免使用 a << -5 這種類型的移位,因為它們的效果是不可預測的,使用類型移位的程序時不可移植的。

編譯器會出現,警告: 左移次數為負 [默認啟用]


再來看看下面的例子:

0x01 << 2 + 3; 結果是多少?

#include <stdio.h>int main (void) {printf ("%d\n", 0x01 << 2 + 3);return 0; } 輸出結果: 32 因為?"+" 號的優先級比移位運算符的優先級高


如果再把例子改寫一下:

0x01 << 2 + 30; ?或者 0x01 << 2 -3; ?這樣行嗎?

#include <stdio.h>int main (void) {printf ("%d\n", 0x01 << 2 + 30);return 0; } 輸出結果: 警告: 左移次數大于或等于類型寬度 [默認啟用] #include <stdio.h>int main (void) {printf ("%d\n", 0x01 << 2 - 3);return 0; } 輸出結果: 警告: 左移次數為負 [默認啟用] 首先考慮的還是運算符優先級,然后看,一個整型數長度為 32 位,左移 32 位則會溢出。左移 -1 位也是不對的。

所以說,左移和右移的位數不能大于數據的長度,不能小于 0。

五、位運算符用法

1、掩碼

flags &= MASK;

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0010 即:

flags &= 0x02;

flags = 0000 0010

這個語句將導致flags的除位 1之外,所有位都被設為 0


2、打開位

flags |= MASK;

例如:flags二進制為 1001 0100 ? MASK二進制為 0000 0010 即:

flags |= 0x02;

flags = 1001 0110

這個語句將flags中的位1設為1并保留其他所有位不變


結合移位運算符

flags |= MASK << n; ? ? ??

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0001 ?n為4即:

flags |= 0x01<<4; ? ?(高電平)

flags = 1001 1110

這個語句將flags的位 3 設為1,并保留其他所有位不變。


3、關閉位

flags &= ~MASK;

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0010 即:

flags &= ~0x02;

flags = 1001 0100

這個語句將flags除位1設為0以外,保留其他所有位不變


結合移位運算符

flags &= ~(MASK << n); ?

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0001 ?n為3即:

flags &= ~(0x01<<3); ? ?(低電平)

flags = 1001 0010

這個語句將flags的位 2 設為0,并保留其他所有位不變 ? ?


4、轉置位

flags ^= MASK;

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0010 即:

flags ^= 0x02;

flags = 1001 0100

轉置一個位表示如果該位打開,則關閉該位,如果該位關閉,則打開該位。


5、查看一位的值

if ((flags & MASK) == MASK)

puts ("Wow);

例如:flags二進制為 1001 0110 ? MASK二進制為 0000 0010 即:

if ((flags & 0x02) == 0x02)

puts ("Wow);

這個語句可判斷flags位1是否為1,由于位運算符的優先級低于==,因此需要在flags & MASK的兩側加上圓括號。


六、位字段

擴展:C語言中的位字段

總結

以上是生活随笔為你收集整理的C语言再学习 -- 位操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。