问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

移位操作符、位操作符和整型提升详解

创作时间:
作者:
@小白创作中心

移位操作符、位操作符和整型提升详解

引用
CSDN
1.
https://blog.csdn.net/2402_89035880/article/details/145663791

本文详细介绍了移位操作符、位操作符和整型提升的概念和使用方法。通过具体的代码示例和二进制运算的详细解释,帮助读者理解这些操作符的工作原理。

移位操作符

左移操作符( << )

左移操作符( << )的规则: 左边抛弃,右边补零

#include <stdio.h>
int main()
{
    int a = 10;
    //00000000000000000000000000001010 -- 10的原码/反码/补码
    int b = a << 1;
    //a向左移动一位
    //移位后
    //00000000000000000000000000010100 -- 补码
    //00000000000000000000000000010100 -- 原码
    //b = 20
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    //a向左移动一位,但a的值不变
    return 0;
}

右移操作符( >> )

右移操作符( >> )的规则: 逻辑右移、算术右移

1.逻辑右移: 左边用0填充,右边丢弃

2.算术右移: 左边用原该值的符号位填充,右边丢弃

右移到底是采用逻辑右移还是算数右移是取决于编译器的,
大部分编译器采用算术右移

#include <stdio.h>
int main()
{
    int a = -10;
    //10000000000000000000000000001010 -- -10的原码
    //11111111111111111111111111110101 -- -10的反码
    //11111111111111111111111111110110 -- -10的补码
    int b = a >> 1;
    //a向右移动一位
    //1.假设是逻辑右移
    //01111111111111111111111111111011 -- 补码
    //01111111111111111111111111111011 -- 原码
    //可知b是一个非常大的正数
    //2.假设是算术右移
    //11111111111111111111111111111011 -- 补码
    //10000000000000000000000000000101 -- 原码
    //b = -5
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    return 0;
}

注意:对于移位运算符,不要移动负数位,这个是标准未定义的。

#include <stdio.h>
int main()
{
    int a = 1;
    int b = a << -1;//err
    return 0;
}

位操作符

按位与( & )

按位与 &

对应的二进制位上,有0就是0,都是1才为1

int main()
{
    int a = -8;
    int b = 6;
    int c = a & b;
    //10000000000000000000000000001000 -- -8的原码
    //11111111111111111111111111110111 -- -8的反码
    //11111111111111111111111111111000 -- -8的补码
    //00000000000000000000000000000110 -- 6的原码/反码/补码
    //a & b 后
    //00000000000000000000000000000000 -- c的原码/反码/补码
    //c = 0
    printf("c = %d\n", c);
    return 0;
}

按位或( | )

按位或 |

对应的二进制位上,有1就是1,都是0才为0

int main()
{
    int a = -8;
    int b = 6;
    int c = a | b;
    //10000000000000000000000000001000 -- -8的原码
    //11111111111111111111111111110111 -- -8的反码
    //11111111111111111111111111111000 -- -8的补码
    //00000000000000000000000000000110 -- 6的原码/反码/补码
    //a | b 后
    //11111111111111111111111111111110 -- c的补码
    //10000000000000000000000000000010 -- c的原码
    //c = -2
    printf("c = %d\n", c);
    return 0;
}

按位异或( ^ )

按位异或 ^

对应的二进制位上,相同为0,相异为1

int main()
{
    int a = -8;
    int b = 6;
    int c = a ^ b;
    //10000000000000000000000000001000 -- -8的原码
    //11111111111111111111111111110111 -- -8的反码
    //11111111111111111111111111111000 -- -8的补码
    //00000000000000000000000000000110 -- 6的原码/反码/补码
    //a ^ b 后
    //11111111111111111111111111111110 -- c的补码
    //10000000000000000000000000000010 -- c的原码
    //c = -2
    printf("c = %d\n", c);
    return 0;
}

按位异或的特点

  1. a ^ a == 0

  2. 0 ^ a == a

  3. a ^ b == b ^ a 支持交换律

按位取反( ~ )

按位取反 ~

0变为1,1变为0

int main()
{
    int a = -1;
    int b = ~a;
    //10000000000000000000000000000001 -- -1的原码
    //11111111111111111111111111111110 -- -1的反码
    //11111111111111111111111111111111 -- -1的补码
    //按位取反操作后
    //00000000000000000000000000000000 -- b的原码/反码/补码
    //b = 0
    printf("b = %d\n", b);
    return 0;
}

整型提升

整型提升

1.有符号整数提升是按照变量的数据类型的符号位来提升的,提升的时候高位补符号位

2.无符号整数提升,高位补0

int main()
{
    char a = 127;
    //00000000000000000000000001111111 int类型的127的原码/反码/补码
    //01111111 -> a的原码/反码/补码 截断后
    //截断的原因:char类型是8个bit位,32个bit位放不下,所以要截断
    char b = 5;
    //00000000000000000000000000000101 int类型的5的原码/反码/补码
    //00000101 -> b的原码/反码/补码 截断后
    char c = a + b;
    //整型提升
    //char在vs编译器上默认是signed char 所以高位补符号位
    //00000000000000000000000001111111 -> 整型提升后的a的补码
    //00000000000000000000000000000101 -> 整型提升后的b的补码
    //00000000000000000000000010000100 -> 相加后的补码
    //10000100 -> c的补码 截断后
    printf("%d\n", c);
    //%d打印c的值 打印的是signed int 类型,c要整型提升,高位补符号位
    //11111111111111111111111110000100 -> 整型提升后的补码
    //10000000000000000000000001111011 
    //10000000000000000000000001111100 -> 原码
    //-124
    return 0;
}


© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号