乐趣区

关于c:C进阶16位运算符

Summary

1)C 语言中的位运算符:

运算符 意义 规定
& 按位与 全 1 得 1,有 0 得 0
I 按位或 有 1 得 1,全 0 得 0
^ 按位异或 雷同为 0,不同得 1
~ 取反 1 变 0, 0 变 1
<< 左移 高位抛弃,低位补 0
·>> 右移 高位补符号位,低位舍弃

2)左移、右移的留神点:

  • 左操作数必须是整数类型

    • char 和 short 被 隐式转换 为 int 后进行操作
  • 右操作数的范畴必须为:[0,31]否则后果未定义(不同编译器处理结果不同)
  • 左移运算符 <<将运算数的二进制位左移,成果 相当于乘以 2 的 n 次方 效率 更高
  • 右移运算符 >>将运算数的二进制位右移,成果 相当于除以 2 的 n 次方 效率 更高
  • 防止位运算符、逻辑运算符、数学运算符等混合运算,如果必须这样,应用括号示意好计算程序。(单算移比、按逻三赋

3)位运算留神点:

  • 位运算没有短路规定,每个操作数都会参加运算
  • 位运算的 后果是整数,而不是 0 或 1
  • 位运算的优先级高于逻辑运算(单算移比 按逻三赋

4)替换两个整形变量的值:

  • Demo1:局部和 形式:不应用两头变量,但存在溢出的问题

    #define SWAP(a, b) \
    {                  \
      a = a + b;       \
      b = a - b;       \
      a = a - b;       \
    }
  • Demo2:位运算 形式:应用异或(两个雷同的值异或后果为 0,任何数和 0 异或仍为自身

    #define SWAP(a, b)    \
    {                     \
      a = a ^ b;          \
      b = a ^ b;          \
      a = a ^ b;          \
    }

位运算符分析

C 语言最后设计用来开发 UNIX 操作系统,操作系统运行于硬件平台之上,必然会波及位运算,须要对硬件的 bit 位(0 和 1)进行操作。C 语言中位运算间接映射到了硬件零碎中的位运算。
位运算符 间接对 bit 位进行操作 ,其 效率最高

1、C 语言中的位运算符

运算符 意义 规定
& 按位与 全 1 得 1,有 0 得 0
I 按位或 有 1 得 1,全 0 得 0
^ 按位异或 雷同为 0,不同得 1
~ 取反 1 变 0, 0 变 1
<< 左移 高位抛弃,低位补 0
·>> 右移 高位补符号位,低位舍弃

2、左移和右移的留神点

  • 左操作数必须是整数类型

    • char 和 short 被 隐式转换 为 int 后进行操作
  • 右操作数的范畴必须为:[0,31]否则后果未定义(不同编译器处理结果不同)
  • 左移运算符 <<将运算数的二进制位左移,成果 相当于乘以 2 的 n 次方 效率 更高
  • 右移运算符 >>将运算数的二进制位右移,成果 相当于除以 2 的 n 次方,效率更高

    • Demo1
      d << 2;               // error, 左操作数必须是整型
      int x = 10 >> 1;      // ok,"右移等效除以 2 的 n 次方",输入 5
      int y = -1 << 1;      // ok,"左移等效乘以 2 的 n 次方",输入 -2
    
      int z = 3 << -1;      // - 1 不在 [0,31] 范畴中,后果未定义,不同编译器不同解决
              // 编译器亦提醒了谬误:Possible overflow in shift operation
      
      // gcc 1,左移 - 1 相当于右移 1,那就除以 2,失去了 1
      // bcc -2147483648,int 的最小值
      // vc 0,原本就未定义,给你 0 把
  • 防止位运算符、逻辑运算符、数学运算符等混合运算,如果必须这样,应用括号示意好计算程序。(单算移比、按逻三赋

    • Demo2
    0x1 << 2 + 3 输入多少?等价于 0x1 << (2 + 3),输入为 32
    
    // 如果这行代码作者本意是先左移,再加法,理论执行后果就不是冀望的
    // 所以在写代码时要尽量用括号 () 来示意分明计算秩序

3、位运算留神点

  • 位运算没有短路规定,每个操作数都会参加运算
  • 位运算的 后果是整数,而不是 0 或 1
  • 位运算的优先级高于逻辑运算(单算移比 按逻三赋

    int i = 0;
    int j = 0;
    int k = 0;
    
    if(++i | ++j & ++k)        // 所有的运算数都会执行到,因而 i j k 判断后都为 1
      printf("cc");

4、位运算利用简略示例

替换两个整形变量的值

  • Demo1:局部和 形式:不应用两头变量,但存在溢出的问题

    #define SWAP(a, b) \
    {                  \
      a = a + b;       \
      b = a - b;       \
      a = a - b;       \
    }
  • Demo2:位运算 形式:应用异或(两个雷同的值异或后果为 0,任何数和 0 异或仍为自身

    #define SWAP(a, b)    \
    {                     \
      a = a ^ b;          \
      b = a ^ b;          \
      a = a ^ b;          \
    }

本文总结自“狄泰软件学院”唐佐林老师《C 语言进阶课程》。
如有错漏之处,恳请斧正。

退出移动版