|
緣起:C語(yǔ)言區(qū)別于其它語(yǔ)言的重要特點(diǎn)是支持位運(yùn)算,使其能夠完成匯編語(yǔ)言所能完成的大部分功能。但是學(xué)校開(kāi)設(shè)的C語(yǔ)言課程中老師往往將位運(yùn)算這一章一代而過(guò),好像這一張根本不重要。但是在實(shí)際的編程中借助于位運(yùn)算往往可以設(shè)計(jì)出簡(jiǎn)潔的算法,使程序簡(jiǎn)化,并且獲得較高的效率。而且在某些對(duì)硬件進(jìn)行控制的編程中,位運(yùn)算是必不可少的。因此筆者參考了相關(guān)書籍,總結(jié)了一些規(guī)律和助記口訣,希望對(duì)讀者有所幫助。
一 優(yōu)先級(jí)(高—〉低)
! ~ 算術(shù)運(yùn)算符 關(guān)系運(yùn)算符 & ^ | && || 賦值
二 移位運(yùn)算 << >;>;
要點(diǎn) 1 它們都是雙目運(yùn)算符,兩個(gè)運(yùn)算分量都是整形,結(jié)果也是整形。
2 左移:右邊空出的位上補(bǔ)0,左邊的位將從字頭擠掉,其值相當(dāng)于乘2。
3 右移:右邊的位被擠掉。對(duì)于左邊移出的空位,如果是正數(shù)則空位補(bǔ)0,若為負(fù)數(shù),可能補(bǔ)0或補(bǔ)1,這取決于所用的計(jì)算機(jī)系統(tǒng)。
移入0的叫邏輯右移,移入1的叫算術(shù)右移,Turbo C采用邏輯右移。
三 位運(yùn)算符的應(yīng)用 (源操作數(shù)s 掩碼mask)
(1) 按位與—— &
1 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)
2 取某數(shù)中指定位 (mask中特定位置1,其它位為0,s=s&mask)
(2) 按位或—— |
常用來(lái)將源操作數(shù)某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s|mask)
(3) 位異或—— ^
1 使特定位的值取反 (mask中特定位置1,其它位為0 s=s^mask)
2 不引入第三變量,交換兩個(gè)變量的值 (設(shè) a=a1,b=b1)
目 標(biāo) 操 作 操作后狀態(tài)
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
四 位運(yùn)算應(yīng)用口訣
清零取反要用與,某位置一可用或
若要取反和交換,輕輕松松用異或
五 應(yīng)用舉例
(1) 判斷int型變量a是奇數(shù)還是偶數(shù)
|- 0 偶數(shù)
a&1=|
|- 1 奇數(shù)
(2) 取int型變量a的第k位 (k=0,1,2……sizeof(int))
a>;>;k&1
(3) 將int型變量a的第k位清0
a=a&~(1<<k)
(4) 將int型變量a的第k位置1
a=a|(1<<k)
(5) int型變量循環(huán)左移k次
a=a<<k|a>;>;16-k (設(shè)sizeof(int)=16)
(6) int型變量a循環(huán)右移k次
a=a>;>;k|a<<16-k (設(shè)sizeof(int)=16)
六 例題
1 實(shí)現(xiàn)一個(gè)函數(shù)itob(),使用移位運(yùn)算將從鍵盤上輸入的整數(shù)轉(zhuǎn)換為它的二進(jìn)制表示形。
解: char * itob(int n,char *ps)
{
int i;
static int size=8*sizeof(int);
for(i=size-1;i>;=0;i--,n>;>;=1)
ps[i]=(1&n)+'0';
ps[size]='\0';
return ps;
}
2 編寫一個(gè)函數(shù) invert_end(),反轉(zhuǎn)一個(gè)值中最后n位,并將結(jié)果返回。
解: int invert_end(int num,int bits)
{
int mask=0;
int bitval=1;
while(bits-- >;0)
{
mask|=bitval;
bitval<<=1;
}
return num^mask;
}
七 實(shí)戰(zhàn)練習(xí)
1 編寫一個(gè)將二進(jìn)制字符串轉(zhuǎn)化為數(shù)值的函數(shù)
若有 char *bin="01001001";
那么可將bin作為參數(shù)傳給該函數(shù),使函數(shù)返回值為25。
2 編寫一個(gè)函數(shù),該函數(shù)接受一個(gè)int參數(shù),并返回該參數(shù)中打開(kāi)的位的數(shù)量。
3 編寫一個(gè)函數(shù),該函數(shù)接受兩個(gè)參數(shù):一個(gè)值和一個(gè)位置。如果制定的位上的值是1,函數(shù)返回1,否則返回0。
八 總結(jié)
(1) 在了解了各種位運(yùn)算的操作原理后,最好熟記各運(yùn)算符的優(yōu)先級(jí)。在閱讀別人寫的代碼是你可以去查書,但自己寫程序時(shí)還是
熟能生巧。
(2) 如你所見(jiàn),在不引入第三變量的情況下使用異或運(yùn)算就可以將兩個(gè)變量的交換,本文給除了操作過(guò)程,你應(yīng)當(dāng)仔細(xì)分析一下。
感覺(jué)就像變魔術(shù)一般神奇
(3) 判斷一個(gè)整數(shù)a的奇偶性通常的做法是看 a%2的結(jié)果是0還是1,這沒(méi)什么不對(duì),但是要知道%運(yùn)算要比相應(yīng)的位運(yùn)算慢的多啦,
對(duì)十個(gè)數(shù)進(jìn)行奇偶判斷就無(wú)所謂啦,哪種方法都o(jì)k,但是若要對(duì)T數(shù)量級(jí)的數(shù)進(jìn)行操作,你就不得不考慮一下效率問(wèn)題了!
本文主要參考了 《C Primer Plus (第四版)》,本文的例題也來(lái)自這本書。
|
|