• C语言 位操作符 >> << & | ^


    目录

    二进制码

    二进制码介绍

    整数7的二进制码 

    整数-7的二进制码

    左移操作符 <<

    例1

    例2 

    右移操作符 >>

    位与操作符 &

    位或操作符 |

    位异或操作符 ^

     Demo:不能创建临时变量,实现两个数的交换


    进制

    • 二进制 0~1
    • 八进制 0~7
    • 十进制 0~9
    • 十六进制 0~9 a~f

    二进制码

    二进制码介绍

    1. 正的整数的源码、反码、补码相同
    2. 负的整数的源码、反码、补码是要计算的
    3. 首个位符号位,符号位为0表示为正数,为1表示为负数
    4. 整数在内存中存储的是补码

    整数7的二进制码 

    7 的二进制为 111,即 1*2的2次方 + 1*2的1次方 + 1*2的0次方

     一个数字式4个字节,一个字节8个bit,即二进制源码如下 

        00000000000000000000000000000111 源码

        00000000000000000000000000000111 反码

        00000000000000000000000000000111 补码

    整数-7的二进制码

        10000000000000000000000000000111 源码

        11111111111111111111111111111000 反码(源码的符号位不变,其他位按位取反就是反码)

        11111111111111111111111111111001 补码(反码+1就是补码)

    左移操作符 <<

            左移操作符:左边丢弃,右边补0

            左移把每一位向左移,相当于每一位二进制位上的数都乘2,所以总体是原来的2倍

    例1

    1. int a = 7;
    2. int b = a << 1;
    3. printf("a = %d\n", a); // 7
    4. printf("b = %d\n", b); // 14 得到二进制源码 0000000000000000000000000001110,即14 —— 1*2的3次方 + 1*2的2次方 + 1*2的1次方 + 0*2的0次方

    例2 

    11111111111111111111111111110010 左移1位后的补码  -1得到反码如下
    二进制码 11111111111111111111111111110010 减去1后,最后一位数字0会变成1,并且往前找到第一个为1的数字,将它变成0,同时它后面所有的0都变成1,最终得到二进制码 11111111111111111111111111110001。
    这是因为减1的操作是对每一个位数进行判断,如果是1就变成0,如果是0就要向前面的位借位,借位的操作是将前一位(即更高位)的数字减1,借位操作会一直向高位进行,直到遇到第一个为1的数字才停止,并将其变成0。
    因此,我们可以将减1的过程表示为以下步骤:

    1. 将最后一位0变成1。
    2. 因为借位的操作会从低位依次向高位进行,所以从最后一位开始,往前找到第一个为1的数字,将其变成0。
    3. 把这个1后面的所有数字(0)都变成1。

    比如 11111111111111111111111111110000  - 1 得到

            11111111111111111111111111101111
            11111111111111111111111111110001 左移1位后的反码  符号位不变,其他位取反得到源码如下
            10000000000000000000000000001110 左移1位后的源码

    1. int A = -7;
    2. printf("B = %d\n", A << 1); // 得到二进制源码10000000000000000000000000001110 即-14

    右移操作符 >>

            右移操作符:分两种

            算术移位:右边丢弃,左边补原符号位(本编译器采用的是算术移位)

            逻辑移位:右边丢弃,左边补0

    11111111111111111111111111111100 右移1位后的补码  -1得到反码如下
    11111111111111111111111111111011 右移1位后的反码   
    10000000000000000000000000000100 右移1位后的源码 即 -4

    1. int c = 7;
    2. printf("c = %d\n", c >> 1); // 3
    3. int C = -7;
    4. printf("C = %d\n", C >> 1); // -4

    位与操作符 &

    按(2进制)位与 ———— 按补码进行运算,有一个为0,则为0,都为1则为1

    1. int a = 3;
    2. int b = -5;
    3. int c = a & b;
    4. /*
    5. 10000000000000000000000000000101 -5的源码
    6. 11111111111111111111111111111010 -5的反码
    7. 11111111111111111111111111111011 -5的补码
    8. 00000000000000000000000000000011 3的补/源码
    9. 00000000000000000000000000000011 与后的补码 (此处符号位是0,即也可看成源码)
    10. */
    11. printf("c=%d\n", c); // 3

    位或操作符 |

    按(2进制)位或 ———— 按补码进行运算,有一个为1,则为1,都为0即0

    1. int a = 3;
    2. int b = -5;
    3. int d = a | b;
    4. /*
    5. 11111111111111111111111111111011 -5的补码
    6. 00000000000000000000000000000011 3的补/源码
    7. 11111111111111111111111111111011 或后的补码 (此处符号位是1,则需要逆推为源码)
    8. 11111111111111111111111111111010 或后的反码
    9. 10000000000000000000000000000101 或后的源码
    10. */
    11. printf("d=%d\n", d); // -5

    位异或操作符 ^

    按(2进制)位异或 ———— 按补码进行运算,相同为0,相异为1

    1. int a = 3;
    2. int b = -5;
    3. int e = a ^ b;
    4. /*
    5. 11111111111111111111111111111011 -5的补码
    6. 00000000000000000000000000000011 3的补/源码
    7. 11111111111111111111111111111000 异或后的补码 (此处符号位是1,则需要逆推为源码)
    8. 11111111111111111111111111110111 异或后的反码
    9. 10000000000000000000000000001000 异或后的源码
    10. */
    11. printf("e=%d\n", e); // -8

     Demo:不能创建临时变量,实现两个数的交换

    位操作符与的规律

            a ^ a = 0

            0 ^ a = a

            a ^ a ^ b = b

    1. 3^3 = 0 -> a^a= 0
    2. 011
    3. 011
    4. 000
    5. 0^5 = 5 -> 0^a = a
    6. 000
    7. 101
    8. 101
    9. 3^3^5 = 5
    10. 3^3^5 = 5 异或操作符支持交换律,如下
    11. 011
    12. 101
    13. 110
    14. 011
    15. 101
    16. int A = 3;
    17. int B = 5;
    18. A = A ^ B; // A = 3 ^ 5
    19. B = A ^ B; // B = 3 ^ 5 ^ 5 ————> 3
    20. A = A ^ B; // A = 3 ^ 5 ^ 3 ————> 5
    21. printf("A=%d B=%d\n", A, B); // 5, 3
  • 相关阅读:
    红队信息收集自动化工具-水泽(ShuiZe)
    生产环境一次Linux时钟同步无法正常同步的问题
    MySQL -- 索引
    【SpringCloud OpenFeign】OpenFeign服务接口调用
    (学习日记)2022.8.9
    区块链的量子威胁:解密数学漏洞
    .NET Core C#系列之XiaoFeng.Data.IQueryableX ORM框架
    math_数集(数集符号)和集合论
    CUDA说明和安装[window]
    Codeforces Round 924 (Div. 2)---->B. Equalize
  • 原文地址:https://blog.csdn.net/dabaooooq/article/details/134096407