11 位运算符 1 C语言中的位运算符 2 左移和右移注意点 3 位运算与逻辑运算的不同

  • 位运算符直接对 bit 位进行操作,其效率最高

    位运算符 含义
    & 按位与
    | 按位或
    ^ 按位异或
    ~ 取反
    << 左移
    >> 右移

2 左移和右移注意点

  • 左操作数必须是整数类型,charshort 类型会被隐式转换为 int 类型后进行移位操作

  • 右操作数的范围必须是:[0,31]

  • 左移运算符 << 将运算数(左操作数)的二进制位左移

    • 规则:高位丢弃,低位补0
    • 左移 n 位相当于乘以 2 的 n 次方,但效率比数学运算符高
  • 右移运算符 >> 将运算数(左操作数)的二进制位右移

    • 规则:高位补符号位,低位丢弃
    • 右移 n 位相当于除以 2 的 n 次方,但效率比数学运算符高
  • 四则运算的运算符(+,-,*,/)优先级高于位运算符

    • 示例:0x1 << 2 + 3 的值是多少?
    • 32:0x1 << 2 + 3 => 0x1 << (2 + 3) => 32
  • 防错准则

    • 避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中
    • 当位运算符,逻辑运算符和数学运算符需要同时参与运算时,尽量使用括号 () 来表达计算次序
  • 示例:交换两个整型变量的值

    #define SWAP1(a,b) 
    {
        int t = a; 
        a = b; 
    	b = t; 
    }
    
    #define SWAP2(a,b) 
    {
        //这里如果a,b都很大,那么可能会产生溢出
        a = a + b; 
        b = a - b; 
        a = a - b; 
    }
    
    #define SWAP3(a,b) 
    {
        a = a ^ b; 
        b = a ^ b;   // =>b = (a ^ b) ^ b = a ^ b ^ b = a 
        a = a ^ b;   // =>a = (a ^ b) ^ a = a ^ b ^ a = b
    }
    

3 位运算与逻辑运算的不同

  • 位运算没有短路规则,每个操作数都参与运算

  • 位运算的结果为整数,而不是 0 或 1

  • 位运算的优先级高于逻辑运算的优先级

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

  • 示例:位运算与逻辑运算的不同

    • Demo

      #include <stdio.h>
      
      int main()
      {
          int i = 0;
          int j = 0;
          int k = 0;
      
          //位运算的混合运算
          if(++i | ++j & ++k)  // <=> if(1 | 1 & 1)
          {
              printf("Run here...
      ");
          }
          printf("i = %d,j = %d,k = %d
      ",i,j,k);
      
          i = 0;j = 0;k = 0;
          //逻辑运算的混合运算
          if(++i || ++j && ++k)  // <=> if((1 && ++i) || (++j && ++k))
          {
              printf("Run here...
      ");
          }
          printf("i = %d,j = %d,k = %d
      ",i,j,k);
          
          return 0;
      }
      
    • 编译运行

      Run here...
      i = 1,j = 1,k = 1
      Run here...
      i = 1,j = 0,k = 0