C語言-位運算子
1、C語言中的位運算子
位運算子直接對bit位進行操作,其效率最高。
左移和右移注意點
-左運算元必須為整數型別
char和short被隱式轉換為int後進行移位操作
-右運算元的範圍必須為: [0, 31]
-左移運算子<<將運算數的二進位制位左移
規則:高位丟棄,低位補0
-右移運算子>>把運算數的二進位制位右移
規則:高位補符號位,低位丟棄
2、有趣的問題
0x1<<2+3的值會是什麼?
A:先算0x1<<2再把中間結果加3 ,最終為7。
B:我覺得先算2 + 3 ,所以結果為32。// 10 0000
C:可以這麼混合計算嗎?
這個問題的真的目的是幹嘛呢?它的求值次序是怎樣的?我們讓編譯器來告訴我們
1 #include <stdio.h> 23 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]
位運算沒有短路規則,所有運算元均會求值
位運算的效率高於四則運算和邏輯運算
運算優先順序:四則運算>位運算>邏輯運算