C語言位運算

西北野狼發表於2024-08-28

C語言裡位運算就是對一個位元(Bit)進行操作,位元(Bit)是計算機的一個電子元件,只有通電和斷電兩種狀態(這也是為什麼計算機會採用二進位制進行運算,1代表通電,0代表不通電),8個位元構成一個位元組(Byte),它是最小的可操作單位.

1712440-7a61eb86f0abfee9.png
CoderDoctorLee

1.按位與運算 (&) :

        一個位元位只有0和1兩個取值,只有運算子號&左右兩邊都為1時結果才為1,否則為0。例如1 & 1為1,0 & 0為0,1 & 0為0。數值在記憶體中以二進位制的形式存在。9 & 5可寫算式如下:                00001001(9的二進位制) & 00000101 (5的二進位制) = 00000001 (1的二進位制) 所以 9 & 5 = 1。嚴格來說,數值在記憶體中以補碼形式存在,整數的補碼與它的二進位制形式相同,負數則不一樣。按位與運算子&會對參與運算的兩個數的所有二進位制位進行&運算。按位與運算通常用來對某些位清0或保留某些位。比如想把一個數字a的高16位清零,保留低16位,可以進行a & 65535運算(65535佔用四個位元組 二進位制表示為00000000000000001111111111111111)。                

程式碼舉例:                                                                                                                                  

unsigned int a = 9;//二進位制:00001001

unsigned int b = 5;//二進位制:00000101

unsigned int c = 0XDE09A32B;//十進位制:3725173547

unsigned int d = 0X0000FFFF;//十進位制:65535

printf("a=%u, b=%u, a&b=%u\n", a, b, a & b);

printf("c=%u, d=%u, c&d(%%d)=%u, c&d(%%X)=%X\n", c, d, c & d, c & d);

結果如下:

a = 9, b = 5, a & b = 1

c = 3725173547, d = 65535, c & d(%d) = 41771, c & d(%X) = A32B

2.按位或運算 (|):

              參與或運算|的兩個二進位制位有一個為1時,結果就為1,兩個都為0時結果才為0。例如1|1為1,0|0為0,1|0為1。9|5可寫算式如下:00001001 (9的二進位制)    |    00000101(5的二進位制)      = 00001101 (13的二進位制)所以9|5=13。按位或運算可以用來將某些二進位制位置為1,而保留某些位。

程式碼舉例:

unsigned int a = 9;//二進位制:00001001

unsigned int b = 5;//二進位制:00000101

unsigned int c = 0XDE09A32B;//十進位制:3725173547

unsigned int d = 0X0000FFFF;//十進位制:65535

printf("a=%u, b=%u, a|b=%u\n", a, b, a | b);

printf("c=%u, d=%u, c|d(%%d)=%u, c|d(%%X)=%X\n", c, d, c | d, c | d);

結果如下:

a=9, b=5, a|b=13

c=3725173547, d=65535, c|d(%d)=3725197311, c|d(%X)=DE09FFFF

3.按位異或運算 (^): 

              按位異或運算參與異或運算^的兩個二進位制位不同時,結果為1,相同時結果為0。也就是說,0^1為1,0^0為0,1^1為0。9^5可寫成算式如下: 00001001 (9的二進位制)  ^ 00000101    (5的二進位制)  =  00001100 (12的二進位制),所以9 ^ 5 = 12。按位異或運算可以用來反轉某些二進位制位。

程式碼舉例:

unsigned int a = 9;//二進位制:00001001

unsigned int b = 5;//二進位制:00000101

unsigned int c = 0XDE09A32B;//十進位制:3725173547

unsigned int d = 0X0000FFFF;//十進位制:65535

printf("a=%u, b=%u, a^b=%u\n", a, b, a ^ b);

printf("c=%u, d=%u, c^d(%%d)=%u, c^d(%%X)=%X\n", c, d, c^d, c^d);

結果如下:

a=9, b=5, a^b=12

c=3725173547, d=65535, c^d(%d)=3725155540, c^d(%X)=DE095CD4

4.取反運算 (~) :

               取反運算取反運算子~為單目運算子,右結合性,作用是對參與運算的數的各二進位按位取反。例如 ~1為0,~0為1。~9的運算為:~0000000000001001 = 1111111111110110所以~9=65526。

5.左移運算 (<<):

               左移運算左移運算子<<用來把運算元的各二進位全部左移若干位,高位丟棄,低位補0。例如:a=9;a<<3;<<左邊是要移位的運算元,右邊是要移動的位數。上面的程式碼表示把a的各二進位向左移動3位。a=00001001(9的二進位制),左移3位後為01001000(十進位制72)。

6.右移運算 (>>):

               右移運算右移運算子>>用來把運算元的各二進位全部右移若干位,低位丟棄,高位補0(或1)。例如:a=9;a>>3;表示把a的各二進位向右移動3位。a=00001001(9的二進位制),右移3位後為00000001(十進位制1)。


補充:

                需要注意的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時,最高位補0,而為負數時,符號位為1,最高位是補0或是補1 取決於編譯器的規定。

程式碼舉例:

unsigned int c = 0X00FFFF00;//十進位制: 3725173547

unsigned int d = 0XFFFF0000;//十進位制: 65535

printf("c=%X, d=%X, c^d(%%X)=%X, c|d(%%X)=%X, c>>4=%X, c<<8=%X\n", c, d, c^d, c|d, c>>4, c<<8);

結果如下:

c=FFFF00, d=FFFF0000, c^d(%X)=FF00FF00, c|d(%X)=FFFFFF00, c>>4=FFFF0, c<<8=FFFF0000

相關文章