找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1603|回復(fù): 0
收起左側(cè)

愛(ài)上位運(yùn)算

[復(fù)制鏈接]
ID:107189 發(fā)表于 2016-3-6 02:09 | 顯示全部樓層 |閱讀模式
緣起: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)自這本書。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表