C语言中<<、>>、&、|的实际用途

举报
CodeAllen 发表于 2021/10/30 01:16:07 2021/10/30
【摘要】 作为一个开发人员,在看别人项目或者看第三方库的源代码时,可能经常会看到譬如a>>4&0x0f这样的写法,对于一些初入行的童鞋来说可能就不是太明白这是什么意思。下面我们就来讲解这几个运算符的实际用途。   一、运算符的含义 运算符含义描述<<左移用来将一个数的各二进制位全部左移N位,高位舍弃...

作为一个开发人员,在看别人项目或者看第三方库的源代码时,可能经常会看到譬如a>>4&0x0f这样的写法,对于一些初入行的童鞋来说可能就不是太明白这是什么意思。下面我们就来讲解这几个运算符的实际用途。

 

一、运算符的含义

运算符 含义 描述
<< 左移 用来将一个数的各二进制位全部左移N位,高位舍弃,低位补0。
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0。
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0。
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1,否则为0。

二、用途

按位与的用途

1.清零

若想对一个存储单元清零,即使其全部二进制位为0,只要对这个存储单元当前的值取反(也就是原来的数中为1变为0,0变为1),然后使二者进行&运算,即可达到清零目的。
比如a=23,b=~a:


  
  1. a:00010111
  2. b:11101000
  3. a&b:00000000

2.取一个数中某些指定位

比如a=23,我想取a的二进制的后面4位数,那么可以找一个后4位是1其余位是0的数b,即b=0x0f(十六进制,转换为二进制为00001111),a&b就得到了a的后四位。


  
  1. a:00010111
  2. b:00001111
  3. a&b:00000111

3.保留指定位

比如a=23(用8bit表示),我想保留其二进制的第4和第6位(最左边为第1位),其余位置0。那么可以找一个第4和第6位是1其余位是0的数b与a进行按位与运算


  
  1. a:00010111
  2. b:00010100
  3. a&b:00010100

按位或的用途

常用来对一个数的某些位置1,其余位不变。比如a=23,我想将其第2和第3位置为1,可以找一个第2、3位是1其余位是0的数与a进行按位或运算。


  
  1. a:00010111
  2. b:01100000
  3. a|b:01110111

三、项目实例

在实际项目中,很多时候&和|都是和>>、<<配合使用的。比如在蓝牙项目开发中,2个设备之间进行日期数据传输时,我们先定一个协议,用4个byte来表示一个日期,其中byte0表示年份的高位数,byte1表示年份的低位数,byte2表示月份,byte3表示日期。
设备端现在收到另外一台设备传过来的日期数据00010100 00010011 00000110 00011101(为了阅读方便我将每个byte之间用空格分开)。那么我要如何解析这个数据来得到实际日期呢?


  
  1. /*
  2. *第一步,获取日期。
  3. *日期是最后一个byte,也就是最后8位,用一个后8位是1其余位是0的数(11111111,十六进制表示是0xff)与数据进行按位与计算即可
  4. */
  5. date = 00010100 00010011 00000110 00011101;
  6. day = date & 0xff;(计算结果是00011101,十进制表示是29,也就是日期是29)。
  7. /*
  8. *第二步,获取月份。
  9. *月份是倒数第2个byte,此时需要先将最后一个byte砍掉(也就是右移8位),然后再和0xff进行按位与运算
  10. *下面代码可以简写成date=date>>8&0xff;
  11. */
  12. date = date>>8; (计算结果是00010100 00010011 00000110)
  13. month = date & 0xff;(计算结果是00000110,十进制表示是6,也就是月份是6月)。
  14. /*
  15. *第三步,获取年份低位。
  16. *先将最后一个byte砍掉(也就是右移8位),然后再和0xff进行按位与运算
  17. *下面代码可以简写成date=date>>8&0xff;
  18. */
  19. date = date>>8; (计算结果是00010100 00010011)
  20. year_low = date & 0xff;(计算结果是00010011,十进制表示是19)。
  21. /*
  22. *第四步,获取年份高位。
  23. *先将最后一个byte砍掉(也就是右移8位),然后再和0xff进行按位与运算
  24. *下面代码可以简写成date=date>>8&0xff;
  25. */
  26. date = date>>8; (计算结果是00010100)
  27. year_heigh = date & 0xff;(计算结果是00010011,十进制表示是20)。

最后将4个数拼起来就得到日期为2019年6月29日。

 

 

 

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/107871373

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。