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] 

            位运算没有短路规则,所有操作数均会求值 

            位运算的效率高于四则运算和逻辑运算 

            运算优先级:四则运算>位运算>逻辑运算

posted @ 2018-12-15 15:27  lemaden  阅读(809)  评论(0编辑  收藏  举报