当前位置:网站首页>C语言 — 位运算操作
C语言 — 位运算操作
2022-07-30 10:52:00 【嵌入式之入坑笔记】
C语言中,特别是在嵌入式的开发中,位操作是很常用的一个知识点,涉及到按位(bit)操作的地方也是很常见的。
本文分享一些C语言中的位操作运算的基础内容。
1、 位与操作( & )
首先必须要区分位与(&)和逻辑与(&&),这两者之间看上去就是多一个少一个的区别,但是最终运算结果却是完全不同的。
位与 & 的真值表:
从上表可以看出,位与 & 的运算原则是:只有当参与运算的两个对象都是真(true 或 1)时,得到的运算结果才是 true 或 1 ,其它的都为flase 或 0。
位与 & 其实就是把参与运算的两个数先分别转换为二进制,然后再相与得到运算之后的结果,如下:
比如:0x01 & 0x03 = 0x01 // 运算如下:
0x01:0 0 0 1
0x03:0 0 1 1
结果:0 0 0 1
2、 位或操作 ( | )
首先必须要区分位与(|)和逻辑与(||),这两者之间看上去就是多一个少一个的区别,但是最终运算结果却是完全不同的。
位与 | 的真值表:
从上表可以看出,位与 | 的运算原则是:只要当参与运算的两个对象中有一个是真(true 或 1)时,得到的运算结果就是 true 或 1 ,只有两个都是 0 才为 flase 或 0。
位与 | 其实就是把参与运算的两个数先分别转换为二进制,然后再相与得到运算之后的结果,如下:
比如:0x01 & 0x03 = 0x03 // 运算如下:
0x01:0 0 0 1
0x03:0 0 1 1
结果: 0 0 1 1
3、位取反操作(~)
位取反就是把十六进制数先转换为二进制,然后把对应的位取反(1 取反变为 0,0 取反变为1)。比如:
比如:0x01 、 0x03 // 运算如下:
0x01:0 0 0 1 ~ 0x01:1 1 1 0 = 0x0D
0x03:0 0 1 1 ~ 0x03:1 1 0 0 = 0x0C
4、位异或操作( ^ )
位异或 ^ 的真值表:
从上表可以看出,位异或 ^ 的运算原则是:当参与运算的两个对象中有一个是真(true 或 1)时,得到的运算结果就是 true 或 1 ;如果两个都是 0 就为 flase 或 0;两个都是 1 就为 flase 或 0。总而言之就是:相同为0,不同为1。
比如:0x01 ^ 0x03 = 0x02 // 运算如下:
0x01:0 0 0 1
0x03:0 0 1 1
结果:0 0 1 0
5、位移操作(<< 、>>)
位移操作中,左移几位就在右边补几个0,右移几位就在左边补几个0,超出数值范围的部分则丢弃。如下:
比如:0x03 // 运算如下:
0x03:0 0 1 1 右移1位:0 1 1 0
0x03:0 0 1 1 右移2位:1 1 0 0
0x03:0 0 1 1 右移3位:1 0 0 0
0x03:0 0 1 1 左移1位:0 0 0 1
0x03:0 0 1 1 左移2位:0 0 0 0
6、位操作的实际运用
6.1、将特定位清零
如果想要把一个特定的数的某一个位清空(置零),使用位与 & 进行操作。比如:
比如:0x0A = 1 0 1 0
想要将第二位清零,其他的位保持不变,用位与 & 操作如下:
方法1:0x0A & 0x0D = 0x08
0x0A = 1 0 1 0
0x0D = 1 1 0 1
结果 :1 0 0 0 = 0x08
方法二:0x0A & ~(1<<1)
6.2、将特定位置 1
如果想要把一个特定的数的某一个位清空(置零),使用位与 & 进行操作。比如:
比如:0x0A = 1 0 1 0
想要将第一位置 1,其他的位保持不变,用位与 | 操作如下:
方法1:0x0A | 0x01 = 0x0B
0x0A = 1 0 1 0
0x01 = 0 0 0 1
结果 :1 0 1 1 = 0x0B
方法二:0x0A | (1<<0)
6.3、特定位取反
如果想要把一个特定的数的某一个位取反,使用异或 ^ 进行操作。比如:
比如:0x0A = 1 0 1 0
想要将第一位取反,其他的位保持不变,用位异或 ^ 操作如下:
0x0A ^ 0x01 = 0x0B
0x0A = 1 0 1 0
0x01 = 0 0 0 1
结果 :1 0 1 1 = 0x0B
注意:异或操作是相同为零,不同为1的运算原则!
6.4、获取特定二进制位
如果想要获取一个数中的某个或者某几个特定的二进制位,可以参考如下操作:
比如:0x0A = 1 0 1 0,想要获取第二和第三位的值,可以按下面方法操作:
T = (0x0A >> 1) & 0x03 得到的二进制值为 0 1
如果想要获取第四位,如下:
T = (0x0A >> 3) & 0x01 得到的二进制值为 1
其他的操作类似。
如果对嵌入式技术感兴趣的,欢迎关注微信公众号“嵌入式之入坑笔记”,一起学习讨论啊!
边栏推荐
猜你喜欢
STM32F1读取MLX90632非接触式红外温度传感器
第3章 信息收集
现在报PMP还来得及参加9月的考试吗?分享敏捷全真模拟题
【AGC】增长服务2-应用内消息示例
Matplotlib--plot markers
360发布面向未来的EDR,全方位守护政企用户终端安全
Meikle Studio-Look at Hongmeng Device Development Practical Notes 7-Network Application Development
Nacos configuration in the project of battle
电压跟随器不要随便加
AB test summary
随机推荐
360 released a future-oriented EDR to protect the security of government and enterprise user terminals in an all-round way
typescript入门之helloworld
[Qualcomm][Network] 网络拨号失败和netmgrd服务分析
【HarmonyOS】【ARK UI】HarmonyOS ets语言怎么实现双击返回键退出
RY-D1/1电压继电器
实现web实时消息推送的7种方案
鸿湖万联扬帆富设备开发板正式合入OpenHarmony主干
Shell system learning function
还在用Swagger?我推荐这款零代码侵入的接口管理神器
定制.NET 6.0的依赖注入
Swift common extension classes and simple encapsulation
xshell使用技巧(赚分享平台怎么样)
@RequestBody 和 @ResponseBody 详解
ODrive应用 #4 配置参数&指令「建议收藏」
Typroa 替代工具marktext
【C和指针第七章】可变参数列表
第1章 Kali与靶机系统
XYplorer 23多语言,最好的管理软件之一
高能产出!腾讯内部的MyCat中间件手册,理论实操齐下
(***Key points***) Flink common memory problems and tuning guide (1)