<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 單片機的C語(yǔ)言中位操作用法

單片機的C語(yǔ)言中位操作用法

作者: 時(shí)間:2016-11-26 來(lái)源:網(wǎng)絡(luò ) 收藏
在對單處機進(jìn)行編程的過(guò)程中,對位的操作是經(jīng)常遇到的。C51對位的操控能力是非常強大的。從這一點(diǎn)上,就可以看出C不光具有高級語(yǔ)言的靈活性,又有低級語(yǔ)言貼近硬件的特點(diǎn)。這也是在各個(gè)領(lǐng)域中都可以看到C的重要原因。在這一節中將詳細講解C51中的位操作及其應用。

1、位運算符

本文引用地址:http://dyxdggzs.com/article/201611/321750.htm

C51提供了幾種位操作符,如下表所示:

運算符

含義

運算符

含義

&

按位與

~

取反

|

按位或

<<

左移

^

按位異或

>>

右移

1)“按位與”運算符(&)

參加運算的兩個(gè)數據,按二進(jìn)位進(jìn)行“與”運算。原則是全1為1,有0為0,即:

0&0=0; 0&1=0; 1&0=0; 1&1=1;

如下例:

a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1

那么如果參加運算的兩個(gè)數為負數,又該如何算呢?會(huì )以其補碼形式表示的二進(jìn)制數來(lái)進(jìn)行與運算。

a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7

在實(shí)際的應用中與操作經(jīng)常被用于實(shí)現特定的功能:

1.清零

“按位與”通常被用來(lái)使變量中的某一位清零。如下例:

a=0xfe; //a=0b 11111110

a=a&0x55;

//使變量a的第1位、第3位、第5位、第7位清零a= 0b 01010100

2.檢測位

要知道一個(gè)變量中某一位是‘1’還是‘0’,可以使用與操作來(lái)實(shí)現。

a=0xf5; //a=0b 11110101

result=a&0x08; //檢測a的第三位,result=0

3.保留變量的某一位

要屏蔽某一個(gè)變量的其它位,而保留某些位,也可以使用與操作來(lái)實(shí)現。

a=0x55; //a=0b 01010101

a=a&0x0f; //將高四位清零,而保留低四位a=0x05

 2)“按位或”運算符(|)            

      參與或操作的兩個(gè)位,只要有一個(gè)為‘1’,則結果為‘1’。即有‘1’為‘1’,全‘0’為‘0’。

              0|0=0; 0|1=1; 1|0=1; 1|1=1;

例如:

        a=0x30|0x0f; //a=(0b00110000)|(0b00001111)=(0b00111111)=0x3f

“按位或”運算最普遍的應用就是對一個(gè)變量的某些位置‘1’。如下例:

a=0x00; //a=0b 00000000

a=a|0x7f; //將a的低7位置為1,a=0x7f

3)“異或”運算符(^)

      異或運算符^又被稱(chēng)為XOR運算符。當參與運算的兩個(gè)位相同(‘1’與‘1’或‘0’與‘0’)時(shí)結果為‘0’。不同時(shí)為‘1’。即相同為0,不同為1。

      0^0=0; 0^1=1; 1^0=1;1^1=0;

例如:

        a=0x55^0x3f; //a=(0b01010101)^(0b00111111)=(0b01101010)=0x6a

異或運算主要有以下幾種應用:

      1.翻轉某一位

         當一個(gè)位與‘1’作異或運算時(shí)結果就為此位翻轉后的值。如下例:

a=0x35; //a=0b00110101

a=a^0x0f; //a=0b00111010 a的低四位翻轉

         關(guān)于異或的這一作用,有一個(gè)典型的應用,即取浮點(diǎn)的相反數,具體的實(shí)現如下:

f=1.23; //f為浮點(diǎn)型變量 值為1.23

f=f*-1; //f乘以-1,實(shí)現取其相反數,要進(jìn)行一次乘運算

f=1.23;

((unsigned char *)&f)[0]^=0x80; //將浮點(diǎn)數f的符號位進(jìn)行翻轉實(shí)現取相反數       

      2.保留原值

       當一個(gè)位與‘0’作異或運算時(shí),結果就為此位的值。如下例:

a=0xff; //a=0b11111111

a=a^0x0f; //a=0b11110000與0x0f作異或,高四位不變,低四位翻轉

      3.交換兩個(gè)變量的值,而不用臨時(shí)變量

       要交換兩個(gè)變量的值,傳統的方法都需要一個(gè)臨時(shí)變量。實(shí)現如下:

void swap(unsigned char *pa,unsigned char *pb)

{

unsigned char temp=*pa;//定義臨時(shí)變量,將pa指向的變量值賦給它

*pa=*pb;

*pb=temp; //變量值對調

}

而使用異或的方法來(lái)實(shí)現,就可以不用臨時(shí)變量,如下:

void swap_xor(unsigned char *pa,unsigned char *pb)

{

*pa=*pa^*pb;

*pb=*pa^*pb;

*pa=*pa^*pb; //采用異或實(shí)現變量對調

}

從上例中可以看到異或運算在開(kāi)發(fā)中是非常實(shí)用和神奇的。

 4)“取反”運算符(~)

         與其它運算符不同,“取反”運算符為單目運算符,即它的操作數只有一個(gè)。它的功能就是對操作數按位取反。也就是是‘1’得‘0’,是‘0’得‘1’。

             ~1=0; ~0=1;

如下例:

a=0xff; //a=0b11111111

a=~a; //a=0b00000000

1.對小于0的有符號整型變量取相反數

d=-1;

//d為有符號整型變量,賦值為-1,內存表示為0b 11111111 11111111

d=~d+1; //取d的相反數,d=1,內存表示0b 00000000 00000001        

  此例運用了負整型數在內存以補碼方式來(lái)存儲的這一原理來(lái)實(shí)現的。負數的補碼方式是這樣的:負數的絕對值的內存表示取反加1,就為此負數的內存表示。如-23如果為八位有符號整型數,則其絕對值23的內存表示為0b00010111,對其取反則為0b11101000,再加1為0b11101001,即為0XE9,與Keil仿真結果是相吻合的:

   2.增強可移植性

          關(guān)于“增強可移植性”用以下實(shí)例來(lái)講解:

          假如在一種單片機中unsigned char類(lèi)型是八個(gè)位(1個(gè)字節),那么一個(gè)此類(lèi)型的變量a=0x67,對其最低位清零。則可以用以下方法:

a=0x67; //a=0b 0110 0111

a=a&0xfe; //a=0b 0110 0110

上面的程序似乎沒(méi)有什么問(wèn)題,使用0xfe這一因子就可以實(shí)現一個(gè)unsigned char型的變量最低位清零。但如果在另一種單片機中的unsigned char類(lèi)型被定義為16個(gè)位(兩個(gè)字節),那么這種方法就會(huì )出錯,如下:

b=0x6767; //假設b為另一種單片機中的unsigned char類(lèi)型變量,值為0b 0110 0111 0110 0111

b=b&0xfe; //如果此時(shí)因子仍為0xfe的話(huà),則結果就為0b 0000 0000 0110 0110即0x0066,而與0x6766不相吻合

上例中的問(wèn)題就是因為不同環(huán)境中的數據類(lèi)型差異所造成的,即程序的可移植性不好。對于這種情況可以采用如下方法來(lái)解決:

a=0x67; //a=0b 0110 0111

a=a&~1; //在不同的環(huán)境中~1將自動(dòng)匹配運算因子,實(shí)現最后一位清零 a=0x66其中~1為0b 11111110

b=0x6767; //a=0b 0110 0111 0110 0111

b=a&~1; //~1=0b 1111 1111 1111 1110,b=0b 0110 0111 0110 0110,即0x6766

5)左移運算符(<<)

  左移運算符用來(lái)將一個(gè)數的各位全部向左移若干位。如:

          a=a<<2

表示將a的各位左移2位,右邊補0。如果a=34(0x22或0b00100010),左移2位得0b10001000,即十進(jìn)制的136。高位在左移后溢出,不起作用。

          從上例可以看到,a被左移2位后,由34變?yōu)榱?36,是原來(lái)的4倍。而如果左移1位,就為0b01000100,即十進(jìn)制的68,是原來(lái)的2倍,很顯然,左移N位,就等于乘以了2N。但一結論只適用于左移時(shí)被溢出的高位中不包含‘1’的情況。比如:

a=64; //a=0b 0100 0000

a=a<<2; //a=0b 0000 0000

其實(shí)可以這樣來(lái)想,a為unsigned char型變量,值為64,左移2位后等于乘以了4,即64X4=256,而此種類(lèi)型的變量在表達256時(shí),就成為了0x00,產(chǎn)生了一個(gè)進(jìn)位,即溢出了一個(gè)‘1’。

          在作乘以2N這種操作時(shí),如果使用左移,將比用乘法快得多。因此在程序中適應的使用左移,可以提高程序的運行效率。

6)右移運算符

         右移與左移相類(lèi)似,只是位移的方向不同。如:

                  a=a>>1

表示將a的各位向右移動(dòng)1位。與左移相對應的,左移一位就相當于除以2,右移N位,就相當于除以2N。

          在右移的過(guò)程中,要注意的一個(gè)地方就是符號位問(wèn)題。對于無(wú)符號數右移時(shí)左邊高位移和‘0’。對于有符號數來(lái)說(shuō),如果原來(lái)符號位為‘0’,則左邊高位為移入‘0’,而如果符號位為‘1’,則左邊移入‘0’還是‘1’就要看實(shí)際的編譯器了,移入‘0’的稱(chēng)為“邏輯右移”,移入‘1’的稱(chēng)為“算術(shù)右移”。Keil中采用“算術(shù)右移”的方式來(lái)進(jìn)行編譯。如下:

d=-32; //d為有符號整型變量,值為-32,內存表示為0b 11100000

d=d>>1;//右移一位d為0b 11110000即-16,Keil采用"算術(shù)邏輯"進(jìn)行編譯

7)位運算賦值運算符

          在對一個(gè)變量進(jìn)行了位操作中,要將其結果再賦給該變量,就可以使用位運算賦值運算符。位運算賦值運算符如下:

&=, |=,^=,~=,<<=, >>=

例如:a&=b相當于a=a&b,a>>=2相當于a>>=2。

  8)不同長(cháng)度的數據進(jìn)行位運算

          如果參與運算的兩個(gè)數據的長(cháng)度不同時(shí),如a為char型,b為int型,則編譯器會(huì )將二者按右端補齊。如果a為正數,則會(huì )在左邊補滿(mǎn)‘0’。若a為負數,左邊補滿(mǎn)‘1’。如果a為無(wú)符號整型,則左邊會(huì )添滿(mǎn)‘0’。

a=0x00; //a=0b 00000000

d=0xffff; //d=0b 11111111 11111111

d&=a; //a為無(wú)符號型,左邊添0,補齊為0b 00000000 00000000,d=0b 00000000 00000000



關(guān)鍵詞: 單片機C語(yǔ)言位操

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>