《第12章_位運(yùn)算》由會(huì)員分享,可在線閱讀,更多相關(guān)《第12章_位運(yùn)算(35頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,*,*,C,程序設(shè)計(jì),第十二章,位運(yùn)算,11/21/2024,1,主要內(nèi)容,12.1,位運(yùn)算符和位運(yùn)算,12.2,位運(yùn)算舉例,12.3,位段,11/21/2024,2,概念,位運(yùn)算是指按二進(jìn)制位進(jìn)行的運(yùn)算。因?yàn)樵谙到y(tǒng)軟件中,常要處理二進(jìn)制位的問題。,例如:將一個(gè)存儲(chǔ)單元中的各二進(jìn)制位左移或右移一位,兩個(gè)數(shù)按位相加等。,語言提供位運(yùn)算的功能,與其他高級(jí)語言(如,PASCAL,)相比,具有很大的優(yōu)越性。,11/21/2024,3,12
2、.1,位運(yùn)算符和位運(yùn)算,運(yùn)算符 含義 運(yùn)算符 含義,按位與,取反,|,按位或,右移,(1),位運(yùn)算符中除以外,均為二目(元)運(yùn)算符,即要求兩側(cè)各有一個(gè)運(yùn)算量。,(2),運(yùn)算量只能是整型或字符型的數(shù)據(jù),不能為實(shí)型數(shù)據(jù)。,語言提供的位運(yùn)算符有:,說明:,11/21/2024,4,12.1.1“,按位與”運(yùn)算符(),按位與是指:,參加運(yùn)算的兩個(gè)數(shù)據(jù),按二進(jìn)制位進(jìn)行“與”運(yùn)算。如果兩個(gè)相應(yīng)的二進(jìn)制位都為,則該位的結(jié)果值為;否則為。即:,,,例:,并不等于,應(yīng)該是按位與運(yùn)算:,注意:,如果參加,&,運(yùn)算的是負(fù)數(shù)(如,-3&-5,),則要以補(bǔ)碼形式表示為二進(jìn)制數(shù),然后再按位進(jìn)行,“,與,”,運(yùn)算。,000
3、00011,(3),&,00000101,(5),00000001,(1),3&5,的值得,11/21/2024,5,按位與的用途:,若想對(duì)一個(gè)存儲(chǔ)單元清零,即使其全部二進(jìn)制位為,只要找一個(gè)二進(jìn)制數(shù),其中各個(gè)位符合以下條件:,原來的數(shù)中為的位,新數(shù)中相應(yīng)位為。,然后使二者進(jìn)行運(yùn)算,即可達(dá)到清零目的。,(1),清零,例:,原有數(shù)為,另找一個(gè)數(shù),設(shè)它為,這樣在原數(shù)為的位置上,該數(shù)的相應(yīng)位值均為。將這兩個(gè)數(shù)進(jìn)行運(yùn)算:,00101011,&,10010100,00000000,11/21/2024,6,(2),取一個(gè)數(shù)中某些指定位,如有一個(gè)整數(shù)(個(gè)字節(jié)),想要取其中的低字節(jié),只需將與,8,個(gè),1,按位
4、與即可。,0 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0,a,b,c,0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0,11/21/2024,7,(3),保留一位的方法:與一個(gè)數(shù)進(jìn)行運(yùn)算,此數(shù)在該位取。,即:,a=84,b=59,c=,a&b,=16,例:,有一數(shù),想把其中左面第、位保留下來,運(yùn)算如下:,01010100,(84),&,00111011,(59),00010000,(16),11/21/2024,8,12.1.2“,按位或”運(yùn)算符(,|,),兩個(gè)相應(yīng)的二進(jìn)制位中只要有一個(gè)為,該位的結(jié)果
5、值為。,即,|,,,|,,,|,,,|,例:,060|017,將八進(jìn)制數(shù),60,與八進(jìn)制數(shù),17,進(jìn)行按位或運(yùn)算。,00110000,|,00001111,00111111,11/21/2024,9,應(yīng)用:,按位或運(yùn)算常用來對(duì)一個(gè)數(shù)據(jù)的某些位定值為。例如:如果想使一個(gè)數(shù)的低位改為,只需將與進(jìn)行按位或運(yùn)算即可。,例:,是一個(gè)整數(shù)(位),有表達(dá)式:,|,則低位全置為,高位保留原樣。,11/21/2024,10,12.1.3“,異或”運(yùn)算符(,),異或運(yùn)算符,也稱,XOR,運(yùn)算符。它的規(guī)則是:,若參加運(yùn)算的兩個(gè)二進(jìn)制位,同號(hào)則結(jié)果為(假),異號(hào)則結(jié)果為(真),即,:00=0,,,01=1,,,10=
6、1,,,11=0,即,:071052=023,(八進(jìn)制數(shù)),00111001,00101010,00010011,例:,11/21/2024,11,()使特定位翻轉(zhuǎn),設(shè)有,想使其低位翻轉(zhuǎn),即變?yōu)椋優(yōu)???梢詫⑺c進(jìn)行,運(yùn)算,即:,運(yùn)算符應(yīng)用:,01111010,00001111,01110101,運(yùn)算結(jié)果的低位正好是原數(shù)低位的翻轉(zhuǎn)。可見,要使哪幾位翻轉(zhuǎn)就將與其進(jìn)行,運(yùn)算的該幾位置為即可。,11/21/2024,12,因?yàn)樵瓟?shù)中的與進(jìn)行,運(yùn)算得,,得,故保留原數(shù),。,例如:,012,00=012,()與相,,保留原值,00001010,00000000,00001010,11/21/2024,1
7、3,()交換兩個(gè)值,不用臨時(shí)變量,例如:,。,想將和的值互換,可以用以下賦值語句實(shí)現(xiàn):,ab,;,ba,;,ab,;,(,),(,ab,的結(jié)果,,a,已變成),(,),(,ba,的結(jié)果,,b,已變成),(,),(,ab,的結(jié)果,,a,已變成),11/21/2024,14,執(zhí)行前兩個(gè)賦值語句:,“,;,”,和,“,;,”,相當(dāng)于,b=,b(ab,),。,再執(zhí)行第三個(gè)賦值語句:,。由于,a,的值等于(,),,b,的值等于(,),因此,相當(dāng)于,a=,,即,a,的值等于,,等于。,得到原來的值。,即等效于以下兩步:,11/21/2024,15,12.1.4“,取反”運(yùn)算符(),是一個(gè)單目(元)運(yùn)算符,
8、用來對(duì)一個(gè)二進(jìn)制數(shù)按位取反,即將變,將變。例如,是對(duì)八進(jìn)制數(shù)(即二進(jìn)制數(shù))按位求反。,0000000000010101,(),1111111111101010,(,八進(jìn)制數(shù),177752),11/21/2024,16,L6,L7,11/21/2024,17,L8,L9,11/21/2024,18,12.1.5,左移運(yùn)算符(),左移運(yùn)算符是用來將一個(gè)數(shù)的各二進(jìn)制位全部左移若干位。,例如:,a=),右移運(yùn)算符是,a2,表示將,a,的各二進(jìn)制位右移,2,位,移到右端的低位被舍棄,對(duì)無符號(hào)數(shù),高位補(bǔ),0,。,例如:,a=017,時(shí),:,a,的值用二進(jìn)制形式表示為,00001111,,舍棄低,2,位,1
9、1,:,a2=00000011,右移一位相當(dāng)于除以,2,右移,n,位相當(dāng)于除以,2n,。,11/21/2024,21,在右移時(shí),需要注意符號(hào)位問題:,對(duì)無符號(hào)數(shù),右移時(shí)左邊高位移入,0,;對(duì)于有符號(hào)的值,如果原來符號(hào)位為,0(,該數(shù)為正,),則左邊也是移入,0,。如果符號(hào)位原來為,1(,即負(fù)數(shù),),則左邊移入,0,還是,1,要取決于所用的計(jì)算機(jī)系統(tǒng)。有的系統(tǒng)移入,0,有的系統(tǒng)移入,1,。移入,0,的稱為“邏輯右移”,即簡(jiǎn)單右移;移入,1,的稱為“算術(shù)右移”。,11/21/2024,22,例:,a,的值是八進(jìn)制數(shù),113755,:,a:1001011111101101,(用二進(jìn)制形式表示),a1
10、:0100101111110110 (,邏輯右移時(shí),),a1:1100101111110110 (,算術(shù)右移時(shí),),在有些系統(tǒng)中,a1,得八進(jìn)制數(shù),045766,而在另一些系統(tǒng)上可能得到的是,145766,。,Turbo C,和其他一些,C,編譯采用的是算術(shù)右移,即對(duì)有符號(hào)數(shù)右移時(shí),如果符號(hào)位原來為,1,,左面移入高位的是,1,。,11/21/2024,23,12.1.7,位運(yùn)算賦值運(yùn)算符,位運(yùn)算符與賦值運(yùn)算符可以組成復(fù)合賦值運(yùn)算符。,例如,:&=,|=,=,=,=,例:,a&=b,相當(dāng)于,a=a&b,a =2,相當(dāng)于,a=a 4,目的是使要取出的那幾位移到最右端,未右移時(shí)的情況 右移,4,位
11、后的情況,11/21/2024,26,設(shè)置一個(gè)低,4,位全為,1,其余全為,0,的數(shù)。,(0 4)&(0 4),程序如下:,#include,void main(),unsigned,a,b,c,d,;,scanf(“%o”,&a,);,b=a4;,c=,(,04);,d=,b&c,;,printf(“%o,%dn%o,%dn”,a,a,d,d,);,運(yùn)行情況如下:(輸入),,,217,(的值),,,13,(的值),輸入的值為八進(jìn)制數(shù),331,,,其二進(jìn)制形式為,11011001,經(jīng)運(yùn)算最后得到的,d,為,00001101,即八進(jìn)制數(shù),十進(jìn)制數(shù),13,。,11/21/2024,27,例,12.
12、2,循環(huán)移位,要求將進(jìn)行右循環(huán)移位,將右循環(huán)移位,即將中原來左面()位右移位,原來右端位移到最左面位。,11/21/2024,28,將的右端位先放到中的高位中,實(shí)現(xiàn)語句:();,將右移位,其左面高位位補(bǔ),,實(shí)現(xiàn)語句:;,將與進(jìn)行按位或運(yùn)算,即,|,;,步驟:,11/21/2024,29,程序如下:,#include,void main(),unsigned,a,b,c,;,int,n;,scanf(“a,=%,o,n,=%,d”,&a,&n,);,b=an;,c=,c|b,;,printf(“%on%o”,a,c,);,運(yùn)行情況如下:,,,3,運(yùn)行開始時(shí)輸入八進(jìn)制數(shù),157653,,,即二進(jìn)制
13、數(shù),1101111110101011,循環(huán)右移位后得二進(jìn)制數(shù),0111101111110101,即八進(jìn)制數(shù),75765,11/21/2024,30,12.3,位,段,信息的存取一般以字節(jié)為單位。實(shí)際上,有時(shí)存儲(chǔ)一個(gè)信息不必用一個(gè)或多個(gè)字節(jié),例如,“真”或“假”用或表示,只需位即可。在計(jì)算機(jī)用于過程控制、參數(shù)檢測(cè)或數(shù)據(jù)通信領(lǐng)域時(shí),控制信息往往只占一個(gè)字節(jié)中的一個(gè)或幾個(gè)二進(jìn)制位,常常在一個(gè)字節(jié)中放幾個(gè)信息。,11/21/2024,31,可以人為地將一個(gè)整型變量,data,分為幾部分。,但是用這種方法給一個(gè)字節(jié)中某幾位賦值太麻煩??梢晕欢谓Y(jié)構(gòu)體的方法。,怎樣向一個(gè)字節(jié)中的一個(gè)或幾個(gè)二進(jìn)制位賦值和改變
14、它的值呢?可以用以下兩種方法,:,(,2,)位段,C,語言允許在一個(gè)結(jié)構(gòu)體中以位為單位來指定其成員所占內(nèi)存長(zhǎng)度,這種以位為單位的成員稱為“位段”或稱“位域”,(bit field),。利用位段能夠用較少的位數(shù)存儲(chǔ)數(shù)據(jù)。,11/21/2024,32,程序如下:,struct,packed-data,unsigned,:;,unsigned,:;,unsigned,:;,unsigned,:;,int,;,data,;,11/21/2024,33,(,1,)位段成員的類型必須指定為,unsigned,或,int,類型。,(,2,),若某一位段要從另一個(gè)字開始存放,可用以下形式定義:,unsigne
15、d,:,1,;,unsigned,b,:;一個(gè)存儲(chǔ)單元,unsigned,:;,unsigned,:;另一存儲(chǔ)單元,a,、,b,、,c,應(yīng)連續(xù)存放在一個(gè)存儲(chǔ)單元中,由于用了長(zhǎng)度為的位段,其作用是使下一個(gè)位段從下一個(gè)存儲(chǔ)單元開始存放。因此,只將,a,、,b,存儲(chǔ)在一個(gè)存儲(chǔ)單元中,,c,另存在下一個(gè)單元,(“,存儲(chǔ)單元”可能是一個(gè)字節(jié),也可能是,2,個(gè)字節(jié),視不同的編譯系統(tǒng)而異,),。,關(guān)于位段的定義和引用的說明:,11/21/2024,34,(3),一個(gè)位段必須存儲(chǔ)在同一存儲(chǔ)單元中,不能跨兩個(gè)單元。如果第一個(gè)單元空間不能容納下一個(gè)位段,則該空間不用,而從下一個(gè)單元起存放該位段。,(4),可以定義無名位段。,(5),位段的長(zhǎng)度不能大于存儲(chǔ)單元的長(zhǎng)度,也不能定義位段數(shù)組。,(6),位段可以用整型格式符輸出。,(7),位段可以在數(shù)值表達(dá)式中引用,它會(huì)被系統(tǒng)自動(dòng)地轉(zhuǎn)換成整型數(shù)。,關(guān)于位段的定義和引用的說明:,11/21/2024,35,