当前位置: 首页 > news >正文

C语言位操作

第一部分位操作符:

位与&

1.注意:&是位与,&&是逻辑与

2.真值表:0+0=0 0+1=0 1+1=1 1+0=0

位与操作特点:只有1和1位与的结果为1。

3.位与和逻辑与的区别:

位与时,两个操作数是按照二进制位批次对应位相与的。如下图

逻辑与是两个操作数作为整体相与的(不是零全为1,非0即1).0XAA+0XF0=1+1=1

位或|

1.注意|为位或,||为逻辑或

2.真值表:0+0=0 0+1=1 1+1=1 1+0=1

位或操作特点:只有0和0位与的结果为0。只要有一个一就为1

3.位与和逻辑与的区别:

位与时,两个操作数是按照二进制位批次对应位相或的。

逻辑或是两个操作数作为整体相或的(不是零全为1,非0即1)

位取反~

1.注意:C语言中位取反是~,逻辑取反是!

2.按位取反是将操作数的二进制位逐个按位取反(0变成1,1变成0).而逻辑取反是真的变成假的假的变成真的。(只有0才是假,不是0全为真)

3.一般按位取反显示结果很大,因为是32位二进制。

4.任何非0的数逻辑取反再取反得到1

任何非零的数按位取反再取反得到本身。

位异或^

1.位异或真值表:1^1=0 0^0=0 1^0=1 0^1=1

2.2个数如果相等结果为0,两个数如果不等结果为1(两个数相异,就进行或操作)

位与 位或 位异或总结:

位与:(任何数,其实就是1或0)与1位与无变化,与0位与都为0;

位或:(任何数,其实就是1或0)与1位或都为1,与0位与无变化;

位异或:(任何数,其实就是1或0)与1位异或会取反,与0位与无变化;

左移位<< 右移位>>:

C语言的移位取决于数据类型

对于无符号数来说,左移时右侧补0(相当于逻辑移位)

对于无符号数来说,右移时左侧补0(相当于逻辑移位)

对于有符号数来说,左移时右侧补0(叫算术移位,相当于逻辑移位)

对于有符号数来说,右移时左侧补符号位(如果是正数就补0,负数就补1)

第二部分位与位或位异或在操作寄存器时的特殊操作

一.先理解结构

SoC :CPU 内核 + 内存 + 各种外设(GPIO、串口、定时器等)是一整套微型系统,是一个芯片

CPU :是专门处理、执行程序的硬件(读取指令,翻译,执行)

外设:就是专门用来干这些实际具体工作的硬件模块

常见外设:

  • GPIO:控制引脚电平,点灯、读取按键。输出高低电平。
  • UART 串口:和别的设备收发字符串,打印日志。
  • SPI / I2C:跟别的芯片通信,比如显示屏、传感器。
  • 定时器 TIM:计时、延时、产生 PWM,控制电机亮度。
  • ADC:读取模拟电压,读电位器、传感器。

寄存器:是CPU与外设的沟通桥梁(因为语言不通)。并且CPU向寄存器中写入一个命令,外设就一直执行命令。

RAM(随机存储器):

1.可读可写,断电数据全部丢失。

2.单片机/Soc里,用来存放正在运行的变量、堆栈

ROM(只读存储器)

1.断电数据不会丢 2.存放你的程序代码、常量。程序烧录在这里

IO口(输入输出口,也是一种外设):就是芯片外面一根根引脚。用来读外面信号,或者输出信号给外部设备。

二.寄存器操作要求

刚刚说寄存器是CPU传入指令控制外设,所以操作寄存器就是操纵硬件。

1.寄存器是按位进行使用的(外设寄存器一般是 32 位,由 32 个bit(位)组成,每 1 个 bit 就是 0 或者 1。并且寄存器里的每一位,各自负责一个功能。

2.寄存器操作要求:在设定特定位时不能影响其他位。

3.操作方法:读,改,写(读出整个寄存器的位,改变想改变的位的位置,最后写入整个已经改完的所有位)

三.特定位清零用&

1.位与:(任何数,其实就是1或0)与1位与无变化,与0位与都为0;

2.如果希望将一个寄存器的某些特定位变成0而不影响其他位,可以构造一个合适的1与0组成的数和这个寄存器原来的值进行位与操作。就可以将特定位清零。

3.举例:假设原来32位寄存器中的值为0XAAAAAAAA(有八个A,每个A代表4位),需要将bit8~bit15清零而其他位不变,可以将这个数与0XFFFF00FF(十六进制F代表二进制1111)进行位与。

四.特定位1用|

位或:(任何数,其实就是1或0)与1位或都为1,与0位与无变化;

2.如果希望将一个寄存器的某些特定位变成1而不影响其他位,可以构造一个合适的1与0组成的数和这个寄存器原来的值进行位或操作。就可以将特定位变1。

3.举例:假设原来32位寄存器中的值为0X123d0c57,需要将bit4~bit7变为1而其他位不变,可以将这个数与0X000000f0(十六进制F代表二进制1111)进行位或。

五,特定位取反用^

1.位异或:(任何数,其实就是1或0)与1位异或会取反,与0位与无变化;

2.按位取反的用法和刚才讲的位与是类似的。我们要构造这样一个数,要取反的指定位为 1,其他位为 0,这个数与原来的数进行位异或即可。

第三部分如何用位运算构建特定二进制数

一.寄存器位操作经常需要特定位给特定值

1.根据上节可知,对寄存器置1清0,取反,在于事先构建一个特别的数,这个数和原来的数进行位与位或,取反。即可达到要求。

2.可以利用相关计算器,直接给出特定32位特定数。但是不直观

3.自己写代码利用位操作符号(主要是移位和位取反)来构建特定二进制数。

二.使用位移获取特定值为一的二进制数

1.首先最简单的就是用移位来获取特定位为1的二进制数。譬如我们需要一个bit3~bit7为1的二进制可以表示:(0X1f<<3)

2.进阶获取bit4~bit6为1,同时bit23~bit28为1,其余为0的二进制数。可以表示:(0X7<<4)|(0X3f<<23)

三.结合位取反获取特定位为0的二进制数

1.特定位为0(比较少)而其余位为1(比较多)适合左移加位取反的方式来构造。

2.思路是:先试图构造出这个数的位相反数,再取反得到这个数

例如要构造bit4~bit10为0其余位为1,就先构造bit4~bit10为1其余位为0,然后对这个数取反。

~(0X7f<<4)

四.总结

1.如果要的数比较少位为1,大部分位为0,则可以通过连续很多个1左移n位得到。

2.如果要的数比较少位为0,大部分位为1,则可以通过先构建其位反数,然后再位取反得到。

3.如果想要的数中连续1的部分不止一个,那么可以通过多端分别构造,然后再彼此位与即可。

第四部分位运算实战演练

回顾:要置 1 用 |,清零用 &,要取反用 ^,~ 和 <<>> 用来构建特定二进制

其中设置就是设置为1,清除就是设置为0.

1、给定一个整型数 a,设置 a 的 bit3,保证其他位不变。

a=a|(1<<3)

2、给定一个整形数 a,设置 a 的 bit3~bit7,保持其他位不变。

a=a|(0X1f<<3)

3、给定一个整形数 a,清除 a 的 bit15,保证其他位不变。

a=a&(~(1<<15))

4、给定一个整形数 a,清除 a 的 bit15~bit23,保持其他位不变。

a=a&~(0x1ff<<15)

5、给定一个整形数 a,取出 a 的 bit3~bit8。

思路:第一步将这个数的bit3~bit8不变,其余位全部清零。第二步右移3位

a=((a&0X1f7)>>3)或者((a&(0x3f<<3))>>3)

6、用 C 语言给一个寄存器的 bit7~bit17 赋值 937(其余位不受影响)。

思路:第一步将bit7~bit17清零,第二步 bit7~bit17赋值

a=a&(~(0X7ff<<7))

a=a|(937<<7)

7、用 C 语言将一个寄存器的 bit7~bit17 中的值加 17(其余位不受影响)。

思路:第一步:先读出bit7~bit17 第二步:将这个数加上17

第三步:将bit7~bit17清零 第四步:加上第二部算出来的bit7~bit17

第一步:tep=a&(0X3ff<<7 ) tep=tep>>7 第二步:tep+=17

第三步:a=a&~(0X3ff) 第四步:a|=tep

8、用 C 语言给一个寄存器的 bit7~bit17 赋值 937,同时给 bit21~bit25 赋值 17。

第五部分.用宏定义来完成位运算

C语言宏定义 #define宏是预处理指令,预处理阶段做简单文本替换,不做类型检查,不占运行时间,不是函数。

http://www.cnnetsun.cn/news/4067673.html

相关文章:

  • 杰理之AUX打断播放提示音死机问题【篇】
  • ANARCI抗体序列编号实战指南:一条命令打通从单条序列到万级批量的全流程
  • 游戏串流新手的周末实录:用 Sunshine 免费把 PC 游戏搬进客厅
  • G-Helper华硕笔记本性能调校终极指南:一文告别Armoury Crate的臃肿与卡顿
  • NetKet 源码架构解析:JAX 之上的三层模块设计,读懂量子库的骨架
  • Markdown 浏览器预览一步到位:markdown-viewer 插件配置指南
  • electron-browser-shell 核心源码解析:electron-chrome-extensions 如何在 Electron 中落地 Chrome 扩展 API
  • AI模型评测实战指南:从通用基准到专项任务,构建有效评估体系
  • ModernHttpClient iOS实战:基于NSURLSession的高性能网络客户端完整解析
  • 免费开源的英雄联盟游戏效率工具 League Akari:完整上手与配置指南
  • 加入yacy_grid_mcp开源社区:从提交Issue到合并Pull Request的完整指南
  • QuantDash 的 klines.batch 方法最大支持多少只股票并发?
  • 华为乾崑智驾与智能安防巡检机器人的AI落地
  • 魔兽争霸3终极优化指南:三步告别宽屏变形、地图超限与帧率锁死
  • DevOps流水线凭据安全:安当SMS让CI/CD零明文
  • HEIC 缩略图插件免费方案:Windows 资源管理器不再满屏灰块的四个步骤
  • 我的联发科手机变砖之后:用 mtkclient 从零完成底层救砖的全记录
  • 网盘直链下载助手保姆级实战:一个免费脚本,把八大网盘的下载入口统一到同一个页面
  • JetBrains One Dark Theme 工作原理:.theme.json 与 XML 配色方案协同机制深度解析
  • 086、梯形速度曲线生成
  • 087、S形速度曲线生成
  • Git作为智能体开发的记忆中枢:解决AI协作中的版本控制难题
  • 3分钟快速上手Tmax-9B-MLX-bf16:Apple Silicon本地部署第一个大模型
  • 黑苹果安装避坑完整指南:长期维护的EFI机型库,让普通PC快速跑上macOS
  • 前端开发中setAttribute报错解析:HTML属性命名规范与动态属性处理
  • 2月轿车销量榜解读:从宝骏310到大众迈腾的消费逻辑与市场趋势
  • BiliDownloader 实测指南:为什么它适合做你的 B 站视频备份工具
  • 一个U盘装下上百个系统镜像:Ventoy多系统启动盘制作实操
  • 死锁与银行家算法详解:读透Operating_System笔记中的经典考点
  • 靠谱的杭州园林绿化排名靠前的公司