《C語言程序設(shè)計》課件第8章_第1頁
《C語言程序設(shè)計》課件第8章_第2頁
《C語言程序設(shè)計》課件第8章_第3頁
《C語言程序設(shè)計》課件第8章_第4頁
《C語言程序設(shè)計》課件第8章_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第8章位運算8.1位運算與位運算符

8.2位段及使用

8.1位運算與位運算符

C語言中提供了六種位運算符,這些運算符的運算功能和優(yōu)先級如表8.1所示。表8.1位運算符含義注意:只有按位求反運算符(~)為單目運算符,其余均為雙目運算符。當兩個運算對象的位數(shù)不同時,系統(tǒng)將自動進行如下處理:

①將兩個運算數(shù)右端對齊;

②將位數(shù)不足的一個運算對象向高位擴充,即無符號數(shù)和正整數(shù)左端用0補齊;負數(shù)左端用1補齊;

(3)對位數(shù)相等的這兩個數(shù)按位進行運算。8.1.1“按位與”運算(&)

“按位與”運算是將參加運算的兩操作對象,按對應(yīng)的二進制位分別進行“邏輯與”運算。運算規(guī)則為:只有兩個相應(yīng)位都為1時,該位的運算結(jié)果才為1;兩個相應(yīng)位的值相異或均為0時,該位的運算結(jié)果為0。如下所示:

1&1=1

0&1=0

1&0=0

0&0=0

【例8.1】

求表達式12&10的值。

程序如下:圖8.1例8.1的運行結(jié)果圖8.2例8.2的輸出結(jié)果

【例8.3】

從鍵盤輸入一個整數(shù),判斷此數(shù)是否能被2整除。

問題分析:一個整數(shù)能否被2整除,只需判斷最低位是0還是1。若最低位為0,則該數(shù)能被2整除;若最低位為1,則該數(shù)不能被2整除。

程序如下:圖8.3例8.3的運行結(jié)果8.1.2“按位或”運算(|)

按位或運算是將參加運算的兩操作對象按對應(yīng)的二進制位分別進行“邏輯或”運算。運算規(guī)則:只有兩個相應(yīng)位都為0時,該位的運算結(jié)果才為0,其他情況下,結(jié)果全為1。如下所示:

0?|?0?=?0

1?|?1?=?1

0?|?1?=?1

1?|?0?=?1

【例8.4】

求表達式12|10的值。

程序如下:圖8.4例8.4的運行結(jié)果輸出結(jié)果如圖8.5所示。

圖8.5例8.5的運行結(jié)果8.1.3“按位異或”運算(^)

按位異或運算是將參加運算的兩操作對象按對應(yīng)的二進制位分別進行“按位異或”運算。運算規(guī)則為:參加運算的兩個運算量,如果兩個對應(yīng)位上的值不同,則該位的結(jié)果為1;如果對應(yīng)位上的值相同,則該位的結(jié)果為0。如下所示:

1^1=0

0^0=0

1^0=1

0^1=1

例如:求表達式210^127的值。

運算過程如下:輸出結(jié)果如圖8.6所示。圖8.6例8.6的運行結(jié)果

程序說明:x=x^y;y=y^x;x=x^y;三條語句相當于以下兩步:

①y=y^(x^y)=y^x^y=y^y^x=0^x=x;

②x=x^y=(x^y)^(y^x^y)=x^y^y^x^y=x^x^y^y^y=y。圖8.7例8.7的運行結(jié)果8.1.4“按位取反”運算(~)

“按位取反”運算符“~”是唯一的一個單目位運算符,用來將一個二進制數(shù)按位取反,即將1變0,將0變1。

運算規(guī)則如下:

~1=0

~0=1

【例8.8】

給出一個數(shù)的原碼,求出該數(shù)的補碼。

問題分析:一個正數(shù)的補碼等于該數(shù)的原碼,一個負數(shù)的補碼等于該數(shù)的反碼加1。程序如下:圖8.8例8.8的運行結(jié)果8.1.5“左移”運算(<<)

左移運算的一般形式為

運算對象<<左移位數(shù)

其中,左移運算符“<<”是雙目運算符,它的作用是將一個數(shù)的各二進制位依次左移若干位(由左移位數(shù)給出),左移時,右端(低位)補0,左端(高位)移出的部分舍去。

設(shè)a=6,則a<<2的值為24。用二進制數(shù)表示運算過程如下:

a:00000110(a=6)

a<<2:00011000(b=24=4*6)左移時,若左端移出的部分不包含有效二進制數(shù)1,則每左移一位,相當于移位對象乘以2。在某些情況下,可以利用左移的這一特征來代替乘法運算,以加快運算速度。

【例8.9】

輸入兩個1位十進制數(shù)字a和b,由a、b組合生成整數(shù)c(c用字符類型表示),并顯示出來。生成規(guī)則是:a的低4位作為c的高4位,b的低4位作為c的低4位。

問題分析:要想用a、b的低4位組成c,需要做以下工作:

①屏蔽掉a、b的高4位;

②a左移4位,使a的低4位成為高4位;

③將a和b拼在一起,形成c。

程序如下:運行情況如圖8.9所示。圖8.9例8.9的運行結(jié)果8.1.6“右移”運算(>>)

右移運算的一般形式為

運算對象>>右移位數(shù)

其中,右移運算符“>>”是雙目運算符,它的作用是將一個數(shù)的各二進制位依次右移若干位(由右移位數(shù)給出),右移時,右端(低位)移出的部分舍去,左端(高位)移入的二進制數(shù)分兩種情況:對于無符號數(shù)和正整數(shù),高位補0;對于負整數(shù),高位補1。

例如:

inta=5,b=-3,x,y;

x=a>>2;

y=b>>2;用二進制數(shù)表示的運算過程如下:

a的二進制補碼表示:00000101

x=a>>2:00000001

b的二進制補碼表示:11111101

y=b>>2:11111111

8.1.7位復合賦值運算符

位運算符和賦值運算符也可以構(gòu)成位復合賦值運算符,類似于算術(shù)運算的復合賦值運算符,見表8.2。表8.2由位運算符構(gòu)成的復合運算符注意:位運算的類型可以是整型(int、unsigned或longint)或字符型(char)數(shù)據(jù)。當兩個運算對象的類型不同時系統(tǒng)會自動進行如下處理:

(1)兩個運算對象按位右對齊;

(2)較短的運算對象高位符號擴展,即如果是正數(shù),高位補0,如果是負數(shù),高位補1。

8.2位?段?及?使?用

在計算機中一般以字節(jié)為單位存放數(shù)據(jù),但實際工作中有時數(shù)據(jù)的表示不必用一個字節(jié),而僅僅占用一個字節(jié)的一位或幾位即可。例如,某系統(tǒng)有7種設(shè)備a、b、c、d、e、f、g,設(shè)備a有4種狀態(tài),設(shè)備b有3種狀態(tài),設(shè)備c有8種狀態(tài),設(shè)備d有8種狀態(tài),設(shè)備e有1種狀態(tài),設(shè)備f有4種狀態(tài),設(shè)備g有6種狀態(tài)。如果每一種設(shè)備的狀態(tài)用一個字節(jié)表示,共需要7個字節(jié)。實際上設(shè)備a有4種狀態(tài),用2位表示即可,即使對于有8種狀態(tài)的設(shè)備c和d,用3位二進制表示也就夠了。7種設(shè)備總共用16位二進制數(shù),用一個無符號整型變量flag來表示即可。利用位運算可以處理這些標志信息,但處理起來比較麻煩。例如對于上述系統(tǒng)的設(shè)備狀態(tài),b設(shè)備3種狀態(tài)用flag的第12、13位表示,如果b的狀態(tài)為01,利用位運算來設(shè)置變量flag的方法可以為

(1)將01存入一個臨時變量temp;

(2)將temp左移12位,將01移至第12、13位;

(3)將flag和temp進行“按位或”運算。

同樣,要想使用flag中存放的設(shè)備b的狀態(tài)信息,可能需要進行以下操作:

(1)將flag內(nèi)容送至臨時變量temp;

(2)將temp與0x3000進行“按位與”運算,屏蔽掉除12、13位的其他位;

(3)temp右移12位。

除了以上方法外,C語言提供了位段操作,可以方便地實現(xiàn)對一個變量的某些位進行處理。所謂位段,是以位為單位定義長度的一種結(jié)構(gòu)類型的成員。上述系統(tǒng)的設(shè)備狀態(tài)可以用位段來實現(xiàn)。8.2.1位段結(jié)構(gòu)類型

位段結(jié)構(gòu)是一種構(gòu)造類型,類型定義的方法為8.2.2位段結(jié)構(gòu)類型變量的定義與引用

1.位段結(jié)構(gòu)類型的變量

定義了位段結(jié)構(gòu)類型后,就可以定義相應(yīng)位段結(jié)構(gòu)類型的變量了。位段結(jié)構(gòu)類型變量的定義方法和其他變量定義方法一樣。例如利用上面定義的類型status可以定義變量flag:

structstatusflag;

這些位段的存放位置由編譯系統(tǒng)分配,不同的編譯系統(tǒng)分配方式不同,有的系統(tǒng)從左到右分配,有的系統(tǒng)則從右到左分配。程序設(shè)計人員不必考慮具體的分配方式,可以直接利用位段名對位段進行操作。

2.位段數(shù)據(jù)的引用

位段數(shù)據(jù)的引用方法和結(jié)構(gòu)體成員的引用方式相同,例如可以為flag的成員a賦值:

flag.a=2;\*a的值為10*\

flag.b=1;\*b的值為01*\

如果所賦的值超過了位段所允許的最大范圍,系統(tǒng)會自動取數(shù)的低位。例如:

flag.a=5;

由于5的二進制形式為101,位段a只有2位,所以結(jié)果a的值為01。圖8.10位段結(jié)構(gòu)中定義無名位段圖8.11無名位段長度為0如果沒有長度為0的無名位段,位段f3應(yīng)該和位段f2相鄰存放,由于長度為0的無名位段的存在,位段f3被分配到下一個單元。

(5)一個位段必須存儲在同一存儲單元,而不能橫跨兩個存儲單元。如果一個單元空間不夠,則系統(tǒng)從下一個單元起存放該位段。例如:由于f1和f2占用了12位,f3需要6位,第一個單元剩余的4位放不下,于是f3從第二個單元開始存放,如圖8.12所示。

因為一個位段不能橫跨兩個單元,所以一個位段的長度不能超過一個存儲單元。

也不能定義位段數(shù)組,并且不能用指針指向位段。圖8.12一個單元空間不夠時的存儲格式圖8.13位段結(jié)構(gòu)中包含非位段成員

(7)位段可以在數(shù)值表達式中引用,并被系統(tǒng)自動轉(zhuǎn)換成整型數(shù)。例如:

data5.f1+5;

data4.f2+15/data5.f1;

以上兩個都是合法的表達式。請讀者自己分析這兩個表達式的值。

位段可以在表達式中引用,所以位段也可以以整型格式輸出。例如:

printf("%d,%d",data2.f1,data1.f2);

當然也可以用%u、%o、%x等格式輸出。8.2.3應(yīng)用舉例

【例8.10】

取一個整數(shù)a(用16位存儲)從右端開始的4~7位。

問題分析:例如,0000000011011001(八進制331,十進制217,4~7位1101的八進制值是15,十進制值是13)。方法:

①先使a右移4位,使要取出的幾位移到最右端,即a>>4;

②設(shè)置一個低4位全為1,其余為0的數(shù)~(~0<<4);

③將上面兩者進行&運算。

程序如下:圖8.14例8.10的運行結(jié)果

【例8.11】

從鍵盤上輸入一個十進制整數(shù),統(tǒng)計該整數(shù)所對應(yīng)的二進制數(shù)中1的個數(shù)。

問題分析:統(tǒng)計一個整數(shù)m中1的個數(shù)有兩種方法。

方法1:

①測試m的第0位是否為1,是則1的個數(shù)加1;

②m右移1位;

③循環(huán)執(zhí)行①、②。

程序如下:圖8.15例8.11的運行結(jié)果方法2:

①k=

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論