日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

C语言再学习 -- 位操作

發(fā)布時(shí)間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 位操作 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、二進(jìn)制

二進(jìn)制是計(jì)算技術(shù)中廣泛采用的一種數(shù)制。二進(jìn)制數(shù)據(jù)是用0和1兩個(gè)數(shù)碼來(lái)表示的數(shù)。它的基數(shù)為2,進(jìn)位規(guī)則是“逢二進(jìn)一”,借位規(guī)則是“借一當(dāng)二”,由18世紀(jì)德國(guó)數(shù)理哲學(xué)大師萊布尼茲發(fā)現(xiàn)。

位:"位(bit)"是電子計(jì)算機(jī)中最小的數(shù)據(jù)單位。每一位的狀態(tài)只能是0或1。
字節(jié):8個(gè)二進(jìn)制位構(gòu)成1個(gè)"字節(jié)(Byte)",它是存儲(chǔ)空間的基本計(jì)量單位。1個(gè)字節(jié)可以?xún)?chǔ)存1個(gè)英文字母或者半個(gè)漢字,換句話(huà)說(shuō),1個(gè)漢字占據(jù)2個(gè)字節(jié)的存儲(chǔ)空間。
字:"字"由若干個(gè)字節(jié)構(gòu)成,字的位數(shù)叫做字長(zhǎng),不同檔次的機(jī)器有不同的字長(zhǎng)。例如一臺(tái)8位機(jī),它的1個(gè)字就等于1個(gè)字節(jié),字長(zhǎng)為8位。如果是一臺(tái)16位機(jī),那么,它的1個(gè)字就由2個(gè)字節(jié)構(gòu)成,字長(zhǎng)為16位。字是計(jì)算機(jī)進(jìn)行數(shù)據(jù)處理和運(yùn)算的單位。?
二進(jìn)制沒(méi)有占位符

二進(jìn)制1011表示:

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


-5 ?二進(jìn)制為 1111 1011 ? ? ? ? ? ?十進(jìn)制數(shù)之間轉(zhuǎn)二進(jìn)制 關(guān)系是 ?取反加一
5的 ?二進(jìn)制 ? 0000 0101
取反 ? ? ? ? ?1111 1010
加一 ? ? ? ? ?1111 1011

有符號(hào)整數(shù)參看:C語(yǔ)言再學(xué)習(xí) -- 負(fù)數(shù)

二進(jìn)制浮點(diǎn)數(shù)參看:C語(yǔ)言再學(xué)習(xí) -- 浮點(diǎn)數(shù)


二、八進(jìn)制

把二進(jìn)制從右向左每三個(gè)數(shù)位分成一組,每一組單獨(dú)轉(zhuǎn)換成十進(jìn)制結(jié)果一定在0到7之間。把所有組的轉(zhuǎn)換結(jié)果按順序書(shū)寫(xiě)就得到數(shù)字的八進(jìn)制表示方式。

例如,八進(jìn)制數(shù)451(在C中寫(xiě)為0451)表示:

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

可以在程序中用八進(jìn)制方式表示數(shù)字必須以0作為開(kāi)頭,采用%o作為占位符可以把一個(gè)整數(shù)的八進(jìn)制表示方式打印在屏幕上


三、十六進(jìn)制

把二進(jìn)制數(shù)字從右向左每四個(gè)數(shù)位分成一組,每組單獨(dú)轉(zhuǎn)換成十進(jìn)制一定在0到15之間,如果轉(zhuǎn)換結(jié)果在10到15之間用英文字母a到f分別表示,把所有轉(zhuǎn)換結(jié)果按順序書(shū)寫(xiě)就得到數(shù)字的十六進(jìn)制表示方式
例 0110 1010 轉(zhuǎn)換成十六進(jìn)制為 6a ?
例 0010 1011 ?43 ?053 ? 2b

在程序中使用十六進(jìn)制方式表示數(shù)字,必須以0x開(kāi)頭,采用%x或者%X作為占位符可以把數(shù)字的十六進(jìn)制表示方式打印在屏幕,上打印結(jié)果中不包含0x。
%x做占位符的時(shí)候打印結(jié)果中的英文字母都是小寫(xiě)的
%X做占位符的時(shí)候打印結(jié)果中的英文字母都是大寫(xiě)的

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

參看:C語(yǔ)言再學(xué)習(xí) -- printf、scanf占位符


參看:二進(jìn)制轉(zhuǎn)換對(duì)照表

擴(kuò)展:進(jìn)制轉(zhuǎn)換器

1、整數(shù)部分的二進(jìn)制轉(zhuǎn)換成十進(jìn)制。

指數(shù)十進(jìn)制數(shù)二進(jìn)制數(shù)
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、小數(shù)部分的二進(jìn)制轉(zhuǎn)換成十進(jìn)制。

記到小數(shù)點(diǎn)后六位就夠了,如果再向后,你可以繼續(xù)除2,不過(guò)這題目可就有些變態(tài)了。

指數(shù)?分?jǐn)?shù)二進(jìn)制十進(jìn)制
?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、二進(jìn)制(B,Binary),八進(jìn)制(O,Octal) 十進(jìn)制(D,Decimalist),十六進(jìn)制(H,Hex)

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

四、位運(yùn)算符

1、二進(jìn)制反碼或按位取反:~

需要確認(rèn)該值是否為unsigned類(lèi)型,如果是有符號(hào)則,正數(shù)為原來(lái)的數(shù)取反、加1

例如:~6?

0000 0110

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


2、&(按位與)(串聯(lián))

只有對(duì)應(yīng)數(shù)位上都是1的時(shí)候結(jié)果才是1
3 二進(jìn)制 ? ? ? 0000 0011 ? ?
5 二進(jìn)制 ? ? ? 0000 0101
按位與 ?& 為 0000 0001
結(jié)果是 1

C也有一個(gè)組合的位與賦值運(yùn)算符:&=。下面兩個(gè)語(yǔ)句產(chǎn)生相同的最后結(jié)果:

val &= 0377; val = val & 0377


3、|(按位或)(并聯(lián))

只要對(duì)應(yīng)數(shù)位中有1則結(jié)果就是1

3 二進(jìn)制 ? ? ?0000 0011 ??
5 二進(jìn)制 ? ? ?0000 0101
按位或 ?| ?為 0000 0111
結(jié)果為 7

C也有一個(gè)組合的位或賦值運(yùn)算符:|=。下面兩個(gè)語(yǔ)句產(chǎn)生相同的最后結(jié)果:

val 1= 0377; val = val | 0377


4、^(按位異或)

如果對(duì)應(yīng)數(shù)位內(nèi)容一樣則結(jié)果是0,否則結(jié)果為1

3 二進(jìn)制 ? ? ? 0000 0011 ??
5 二進(jìn)制 ? ? ? 0000 0101
按異或 ?^ 為 0000 0110
結(jié)果位 6

C也有一個(gè)組合的位異或賦值運(yùn)算符:^=。下面兩個(gè)語(yǔ)句產(chǎn)生相同的最后結(jié)果:

val ^= 0377; val = val ^0377


5、移位運(yùn)算符

移動(dòng)操作符可以把數(shù)字中每個(gè)二進(jìn)制數(shù)位統(tǒng)一想左或者向右移動(dòng)n個(gè)位置,移動(dòng)操作會(huì)得到一個(gè)新數(shù)字,不會(huì)修改原來(lái)的數(shù)字。

1) <<表示向左移動(dòng)操作

向左移動(dòng)是右邊空出來(lái)的位置上一定補(bǔ)充0
例如 二進(jìn)制 ?(0000 0011) << 2 ?向左移動(dòng)兩位結(jié)果為 ?0000 1100
3 ? ?0000 0011 ? ? 3 x 2^2 =12
? ? ? 0000 1100

再如:

-5 << 2 = -20

也可以這么理解,向左移動(dòng)n位相當(dāng)于乘以2的n次方。


2) >>表示向右移動(dòng)操作

對(duì)于unsigned類(lèi)型,右移時(shí)使用0填充左端空出的位。對(duì)于有符號(hào)類(lèi)型,結(jié)果依賴(lài)于機(jī)器。空出的位可能用0填充,或者使用符號(hào)(最左端的)位的副本填充。

例如 二進(jìn)制 (0000 1100) >> 2 向右移動(dòng)兩位結(jié)果為 0000 0011

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

? ? ? ? ?0000 0011

也可以這么理解,相對(duì)于unsigned類(lèi)型而言向右移動(dòng)n位相當(dāng)于除以2的n次方


注意:

應(yīng)避免使用 a << -5 這種類(lèi)型的移位,因?yàn)樗鼈兊男Ч遣豢深A(yù)測(cè)的,使用類(lèi)型移位的程序時(shí)不可移植的。

編譯器會(huì)出現(xiàn),警告: 左移次數(shù)為負(fù) [默認(rèn)啟用]


再來(lái)看看下面的例子:

0x01 << 2 + 3; 結(jié)果是多少?

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


如果再把例子改寫(xiě)一下:

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

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

所以說(shuō),左移和右移的位數(shù)不能大于數(shù)據(jù)的長(zhǎng)度,不能小于 0。

五、位運(yùn)算符用法

1、掩碼

flags &= MASK;

例如:flags二進(jìn)制為 1001 0110 ? MASK二進(jìn)制為 0000 0010 即:

flags &= 0x02;

flags = 0000 0010

這個(gè)語(yǔ)句將導(dǎo)致flags的除位 1之外,所有位都被設(shè)為 0


2、打開(kāi)位

flags |= MASK;

例如:flags二進(jìn)制為 1001 0100 ? MASK二進(jìn)制為 0000 0010 即:

flags |= 0x02;

flags = 1001 0110

這個(gè)語(yǔ)句將flags中的位1設(shè)為1并保留其他所有位不變


結(jié)合移位運(yùn)算符

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

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

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

flags = 1001 1110

這個(gè)語(yǔ)句將flags的位 3 設(shè)為1,并保留其他所有位不變。


3、關(guān)閉位

flags &= ~MASK;

例如:flags二進(jìn)制為 1001 0110 ? MASK二進(jìn)制為 0000 0010 即:

flags &= ~0x02;

flags = 1001 0100

這個(gè)語(yǔ)句將flags除位1設(shè)為0以外,保留其他所有位不變


結(jié)合移位運(yùn)算符

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

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

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

flags = 1001 0010

這個(gè)語(yǔ)句將flags的位 2 設(shè)為0,并保留其他所有位不變 ? ?


4、轉(zhuǎn)置位

flags ^= MASK;

例如:flags二進(jìn)制為 1001 0110 ? MASK二進(jìn)制為 0000 0010 即:

flags ^= 0x02;

flags = 1001 0100

轉(zhuǎn)置一個(gè)位表示如果該位打開(kāi),則關(guān)閉該位,如果該位關(guān)閉,則打開(kāi)該位。


5、查看一位的值

if ((flags & MASK) == MASK)

puts ("Wow);

例如:flags二進(jìn)制為 1001 0110 ? MASK二進(jìn)制為 0000 0010 即:

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

puts ("Wow);

這個(gè)語(yǔ)句可判斷flags位1是否為1,由于位運(yùn)算符的優(yōu)先級(jí)低于==,因此需要在flags & MASK的兩側(cè)加上圓括號(hào)。


六、位字段

擴(kuò)展:C語(yǔ)言中的位字段

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。