1. 程式人生 > >C語言-位運算子

C語言-位運算子

1、C語言中的位運算子 

  位運算子直接對bit位進行操作,其效率最高。

左移和右移注意點 

-左運算元必須為整數型別 

   charshort被隱式轉換為int後進行移位操作 

-右運算元的範圍必須為: [0, 31] 

左移運算子<<將運算數的二進位制位左移 

   規則:高位丟棄,低位補0 

右移運算子>>把運算數的二進位制位右移 

  規則:高位補符號位,低位丟棄

 2、有趣的問題

0x1<<2+3的值會是什麼?

        A:先算0x1<<2再把中間結果加3 ,最終為7。 

        B:我覺得先算2 + 3 ,所以結果為32。// 10 0000

        C:可以這麼混合計算嗎? 

這個問題的真的目的是幹嘛呢?它的求值次序是怎樣的?我們讓編譯器來告訴我們

 1 #include <stdio.h>
 2
3 int main() 4 { 5 printf("%d\n", 3 << 2); 6 printf("%d\n", 3 >> 1); 7 printf("%d\n", -1 >> 1); 8 printf("%d\n", 0x01 << 2 + 3); 9 10 printf("%d\n", 3 << -1); // oops! 11 12 return 0; 13 }

這裡分別有三款編譯器:

bcc, gcc,vcc,他們的差異很大,讀者可以直接試下。但第10行結果應該是32,gcc對左移-1,當作右移1位,其他的報錯或者結果不對。

小貼士:

防錯準則: 

                -避免位運算子,邏輯運算子和數學運算子同時出現在一個表示式中 

                -當位運算子,邏輯運算子和數學運算子需要同時參與運算時, 

                 -  儘量使用括號()來表達計算次序 

小技巧: 

                -左移n位相當於乘以2的n次方,但效率比數學運算子高 

                -右移n位相當於除以2的n次方,但效率比數學運算子高 

程式設計實驗-交換兩個整形變數.cpp:

  

 1 #include <stdio.h>
 2 
 3 #define SWAP1(a, b)    \
 4 {                      \
 5     int t = a;         \
 6     a = b;             \
 7     b = t;             \
 8 }
 9 
10 #define SWAP2(a, b)    \
11 {                      \
12     a = a + b;         \
13     b = a - b;         \
14     a = a - b;         \
15 }
16 
17 #define SWAP3(a, b)    \
18 {                      \
19     a = a ^ b;         \
20     b = a ^ b;         \
21     a = a ^ b;         \
22 }
23 
24 int main()
25 {
26     int a = 1;
27     int b = 2;
28     
29     
30     printf("a = %d\n", a); 
31     printf("b = %d\n", b); 
32     
33     SWAP3(a ,b);
34     
35     printf("a = %d\n", a); 
36     printf("b = %d\n", b); 
37     
38     return 0;
39 }

3.位運算與邏輯運算

位運算與邏輯運算不同: 

                 -位運算沒有短路規則,每個運算元都參與運算 

                 -位運算的結果為整數,而不是0或1 

                 -位運算優先順序高於邏輯運算優先順序

4.例項分析:

  混淆概念的邏輯判斷

 1 #include <stdio.h>  
 2   
 3 int main()  
 4 {  
 5     int i = 0;  
 6     int j = 0;  
 7     int k = 0;  
 8       
 9     if( ++i | ++j & ++k )  
10     {  
11         printf("Run here...\n");  
12     }  
13       
14     return 0;  
15

5.小結

            位運算子只能用於整數型別 

            左移和右移運算子的右運算元範圍必須為[0, 31] 

            位運算沒有短路規則,所有運算元均會求值 

            位運算的效率高於四則運算和邏輯運算 

            運算優先順序:四則運算>位運算>邏輯運算