关于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语言进阶课程》。
如有错漏之处,恳请斧正。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理