C -- 位操作基础

位操作运算符

###基本运算符*

运算符~&|^<<>>
含义按位反按位与按位或按位异或左移右移

1、按位反: ~
一元运算符,逐位取反,产生二进制反码;
例:

~(10010001) == 01101110;

2、按位与: &
二元运算符,逐位比较,都真才真(1 & 1 = 1);
例:

(10010001) & (00110000) == 00010000;

3、按位或: |
二元运算符,逐位比较,有真即真(1 | 0 = 1 或 1 | 1 = 1);
例:

(11101011) | (00100100) == 11101111;

4、按位异或: ^
二元运算符,逐位比较,一真一假为真(1 ^ 0 = 1);
例:

(11010011) ^ (10101010) == 01111001;

5、左移and右移: << and >>
左移运算符,将其左侧运算对象的每一位向左移动右侧运算对象指定的位数。左侧移除值丢失,右侧空出位置用0填充。
例:

(00001010) << 2 == (00101000); //相当于向高位移动

右移运算符,将其左侧运算对象的每一位向右移动右侧运算对象指定的位数。右侧移除值丢失,左侧空出位置,对于无符号类型用0填充,有符号类型不确定取决于机器,填充值不确定。
例:

//若为无符号类型
(10001010) >> 2 == (00100010); //相当于向低位移动

总的来说,左移产生新值每一个位向低位移动,右移产生新值将每一个位向高位移动,但是都是对副本操作,也就是说不改变原有值。若要改变可与赋值运算符结合形成<<=和>>=。

num >> n; //相当于num * pow(2,n)
num << n; //相当于num / pow(2,n)

以上中二元运算符&、|、^、>>、<<都可以与幅值运算符组合
如:
val |= (0o377)
即 val = val | (0o377)

###用法

假设有两个变量:
MASK 0 0 0 0 0 0 1 0
FLAG 1 0 0 1 0 1 1 0

1、掩码(mask),所谓掩码是指一些设置为1(透明)、0(不透明)的位组合。
表达式 FLAG & MASK
相当于用掩码覆盖在flags的位组合上,使MASK中为1的透明可见,为0的不可见;且若flags宽度 > MASK宽度,MASK宽度决定运算结果的宽度。
例:

(FLAG & MASK) == 00000010;

2、打开位(设置值),打开一个值中特定位,其他位保持不变。
表达式 FLAGS |= MASK
相当于把FLAGS中的1号位设置为1(打开),其他位保持不变。
例:

(FLAGS | MASK) == 10010110;

3、关闭位(清空位),类似于打开位,关闭特定位,其他位保持不变。
表达式 FLAGS & ~(MASK)
相当于把FLAGS中的1号位设置为0(关闭),其他位保持不变。
例:

(FLAGS & (~MASK)) == 10010100;

4、切换位,指打开关闭位,关闭打开位。
异或运算四种情况:
掩码MASK中为1,成功切换位;
1 ^ 1 = 0
1 ^ 0 = 1
掩码MASK中为0,保持不变;
0 ^ 0 = 0
0 ^ 1 = 1
例:

mask = 10110110;
flags = 00001111;
mask ^ flags = 10111001

flags中与mask中为1的位相对应的位都被切换了,mask为0相对应的flags的位保持不变;

5、检查位的值,检查某位是否被设置为1?不能直接比较flags与mask,即使某位为1,其他位会导致比较结果为假。因此,必须覆盖flags中其他位,只比较1号位;
例:

if((flags & mask) == mask) puts("Wow!");

掩码宽度至少要与其覆盖值相同,避免信息漏过边界

6、移位运算符,针对2的幂提供了快速有效的乘法和除法,类似于十进制中移动小数点来乘以或除以10。

number << n	 //number乘以2的n次幂
number >> n  //如果number为非负,则用number除以2的n次幂

还可用于从较大单元中提取一些位。
例如,假设用一个unsign char类型的值表示颜色,低阶字节存储红色强度,下一字节存储绿色强度,第三个字节存储蓝色强度。我们可以依次提取出来存储到3个不同的unsiged char类型中。

#define BYTE_MASK 0xff
unsigned long color = 0x002a162f;
unsigned char blue, green, red;
red = color & BYTE_MASK;
green = (color >> 8) & BYTE_MASK;
red = (color >> 16) & BYTE_MASK;

2019.12.1
修炼之路(一)
未完待续
归期不定
by lx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值