C語言位操作符的使用
C語言的設計具備了組合語言的運算能力,它支援全部的位操作符。位操作符是對位元組或字中的位進行測試、置位或移位處理,在對微處理器的程式設計中,特別適合對暫存器、I/O埠進行操作。
6種偉操作符:
(1) & :按位“與”——僅當兩個運算元為1時,結果為1,否則為0。如:1000 1000 & 1000 0001 = 1000 0000;
(2) | :按位“或”——僅當兩個運算元為0時,結果為0,否則為1。如:1000 1000 | 1000 0001 = 1000 1001;
(3) ^:按位“異或”——僅當兩個運算元不同時,相應的輸出結果才為1,否則為0。
如:1000 1000 ^ 1000 0001 = 0000 1001 ;
(4) ~ :“取反”——把1置為0,0置為1。如:~1000 1000 = 0111 0111;
(5) <<: “左移”——將變數的各位按要求向左移動若干位。如:0000 1000 <<3 = 0100 0000;
(6) >>: “右移”——將變數的各位按要求向右移動若干位。如:0000 1000>>3=0000 0001;
位運算子的應用:
(1)直接交換兩個變數的值
例如,若有變數a = 3,b = 4,想要交換它們的值,可以做如下一組操作:
a ^ = b
b ^ = a
a ^ = b
首先,a ^ = b:
a0000 0011
^b0000 0100
a =0000 0111
其次,b ^ = a:
b0000 0100
^a0000 0111
b =0000 0011
最後,a ^ = b:
a0000 0111
^b0000 0011
a =0000 0100
這樣,
(2)快速乘除運算
移位操作可用於整數的快速乘除運算,左移一位等效於乘2,而右移一位等效於除以2。
如:x = 7,二進位制表達為:0000 0111,
x < < 10000 1110,相當於: x =2*7=14,
x < < 30111 0000,相當於: x=14*2*2*2=112
x < < 21100 0000,x= 192
在作第三次左移時,其中一位為1的位移到外面去了,而左邊只能以0補齊,因而便不等於112*2*2=448,而是等於192了。當x按剛才的步驟反向移動回去時,就不能返回到原來的值了,因為左邊丟掉的一個1,再也不能找回來了:
x > > 20011 0000
x > > 30000 0110x=48/8=6
x > > 10000 0011x=6/2=3
(3)將暫存器指定位置為1
PORTA |= (1<<n) 將porta的第n為置為1,其他為不變。比如說,你如果想將第4位置1,就使用:
PORTA | = (1<< 4) 就行了。當然,也可以使用:
PORTA | = (1<< 7) | (1<< 4 ) | (1<< 0) 這樣的指令一次將設第8、5和1位置1,但又不影響到其它位的狀態。
(4)將暫存器指定位置為0
PORTA &= ~(1<<n )
這條指令將暫存器的任意位清0,而又不影響其它位的現有狀態。比如說,你如果想將第4位清0,就使用:
PORTA & = ~ (1<< 4) 就行了。
下面是POJ 3748題,應用了位操作符:
/*
位操作
Description
假設你工作在一個32位的機器上,你需要將某一個外設暫存器的第X位設定成0(最低位為第0位,最高位為第31位),
將第Y位開始的連續三位設定成110(從高位到低位的順序),而其他位保持不變。對給定的暫存器值R,及X,Y,
程式設計計算更改後的暫存器值R。
Input
僅一行,包括R,X,Y,以逗號","分隔,R為16進製表示的32位整數,X,Y在0-31之間且Y>=3,(Y-X)的絕對值>=3,保證兩次置位不會重合
Output
更改後的暫存器值R(16進位制輸出)
Sample Input
12345678,0,3
Sample Output
1234567c
Source
*/
#include <stdio.h>
int main()
{
int R, X, Y;
scanf("%x,%d,%d",&R,&X,&Y);
R &= ~(1<<X); // 將R的第X位設定為0
R |= (1<<Y); // 將R的第Y位設定為1
Y--;
R |= (1<<Y); // 將R的第Y-1位設定為1
Y--;
R &= ~(1<<Y); // 將R的第Y-2位設定為0
printf("%x/n",R);
return 0;
}