位操作----位运算符详解(按位与(&),按位或(|),按位异或(^),按位取反(~)以及左移(<<)右移(>>))

前言

此文主要为了本人复习知识
在学习位操作时,我们首先要清楚的是:

1.位运算的符操作数只能是整型和字符型对象
2.在计算机中数据都是以二进制存储的(位操作就是直接对二进制进行操作)

       原码、反码、补码,这是学习位操作必不可少的知识

一、原码、反码、补码

   整数以二进制补码的形式存储在内存中,对于正数的:原码、反码、补码
都相同,以下规则针对负整数。

原码:根据数值写出的二进制序列
反码:以原码为基础,原码符号位不变其他位按位取反(按位取反:0变1,1变0)
补码:在反码的基础上加1

      下面我们看示例(对应上面规则来看)

例:正整数1

原码:00000000  00000000  00000000  00000001

反码:00000000  00000000  00000000  00000001

补码:00000000  00000000  00000000  00000001

负整数1(-1)

原码:10000000  00000000  00000000  00000001

反码:11111111  11111111  11111111  11111110(按位取反,符号位不变)

补码:11111111  11111111  11111111  11111111( 反码 + 1

二、按位逻辑运算符

1、按位取反:~

 这里按位取反符号位也改变

例:a=1(有符号整型)

    一定要写个代码跑一跑
代码:
int a = 1;
printf("%d",~a)
a=1
补:00000000 00000000 00000000 00000001

~a
补:11111111 11111111 11111111 11111110(可以看到对1,取反后得到的补码,符号位为1)
我们要想得到它的值,需要先将补码转换为原码

反:11111111 11111111 11111111 11111101

原:10000000 00000000 00000000 00000010(结果为-2

a=1(无符号整型)

代码:
size_t a = 1;//无符号整型
printf("%zu",~a);

a=1
补:00000000 00000000 00000000 00000001

~a
补:11111111 11111111 11111111 11111110(因为不含符号位,得到的就是正整数,即补码就是原码)

2.按位与:&

二元运算符&通过逐位比较两个运算对象, 生成一个新值。对于每个位,只有两个运算对象中相应的位都为1时,结果才为1(从真/假方面看,只有当两个位都为真时,结果才为真----计算机0为假,非零为真)。
例:

a=1:
补:00000000 00000000 00000000 00000001

b=-1:
补:11111111 11111111 11111111 11111111

a&b:
    00000000 00000000 00000000 00000001
              &
    11111111 11111111 11111111 11111111
结果:
    00000000 00000000 00000000 000000011

3、按位或:|

二元运算符|,通过逐位比较两个运算对象,生成一个新值。对于每个位,如果两个运算对象中相应的位为1,结果就为1(从真/假方面看,如果两个运算算对象中相应的一个位为真或两个位都为真,那么结果为真)。
例:

a=1:
补:00000000 00000000 00000000 00000001

b=-1:
补:11111111 11111111 11111111 11111111

a&b:
    00000000 00000000 00000000 00000001
                |
    11111111 11111111 11111111 11111111
结果:
补:11111111 11111111 11111111 11111111
原:10000000 00000000 00000000 00000001-1

4、按位异或:^

二元运算符^逐位比较两个运算对象。对于4每个位,如果两个运算对象中相应的位一个为1(但不是两个为1),结果为1(从真/假方面看,如果两个运算对象中相应的一个位为真且不是两个为同为1,那么结果为真)。
例:

a=1:
补:00000000 00000000 00000000 00000001

b=-1:
补:11111111 11111111 11111111 11111111

a&b:
    00000000 00000000 00000000 00000001
                ^
    11111111 11111111 11111111 11111111
结果:
补:11111111 11111111 11111111 11111110
原:10000000 00000000 00000000 00000010-2
  可以想影响如果两个相同的数进行异或,它的结果不就是0了吗

5、左移(<<)、右移(>>)

          该操作产生了一个新的位值,但是不改变其运运算对象,类似与+、-等操作符,要想获得操作后
     的结果可以配合赋值符使用。
a=-3:
补:11111111 11111111 11111111 11111101

a<<1
补:11111111 11111111 11111111 11111010
原:10000000 00000000 00000000 00000110-6)
a>>1
补:11111111 11111111 11111111 11111110
原:10000000 00000000 00000000 00000010-2

总结

需要注意的是对于负整数,原码、反码、补码之间的转化,和有符号、无符号之间的差异;其实这一块并没有难度,主要理解后灵活使用,下面是关于这方面的例题:
1、只出现一次的数i
2、只出现一次的数ii
3、只出现一次的数iii

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值