C语言的位操作与位字段

C语言中的位操作允许程序员直接在整型变量的单个位或位组上进行操作。这种操作在许多低级编程任务中非常有用,尤其是在嵌入式系统编程中,如硬件操作、设备驱动及性能优化等场景。位操作主要使用以下几种位操作符:
& (按位与)
| (按位或)
^ (按位异或)
~ (按位取反)
<< (左移)
>>(右移)
我们来深入浅出地了解一下每个操作符及其用法。

1. 按位与(&)


按位与操作符&用于将每个位与操作数的对应位进行与运算。如果两个相应的位都是1,则结果为1,否则为0。
示例代码:

unsigned char a = 0b11001100;
unsigned char b = 0b10101010;
unsigned char result = a & b; // result将会是 0b10001000

2. 按位或(|)


按位或操作符|用于将每个位与操作数的对应位进行或运算。如果两个相应的位中至少有一个为1,则结果为1,如果都是0,结果为0。
示例代码:

unsigned char a = 0b11001100;
unsigned char b = 0b10101010;
unsigned char result = a | b; // result将会是 0b11101110

3. 按位异或(^)


按位异或操作符^用于将每个位与操作数的对应位进行异或运算。如果两个相应的位一个为1另一个为0,则结果为1,否则为0。
示例代码:

unsigned char a = 0b11001100;
unsigned char b = 0b10101010;
unsigned char result = a ^ b; // result将会是 0b01100110

4. 按位取反(~)


按位取反操作符~用于将操作数的每一个位取反。即0变1,1变0。
示例代码:

unsigned char a = 0b11001100;
unsigned char result = ~a; // result将会是 0b00110011

5. 位左移(<<)


位左移操作符<<用于将操作数的所有位统一向左移动指定的位数,左边界之外的位被丢弃,右边界空出来的位填充0。
示例代码:

unsigned char a = 0b11001100;
unsigned char result = a << 2; // result将会是 0b00110000

6. 位右移(>>)


位右移操作符>>与位左移类似,但方向相反。它将操作数的所有位统一向右移动指定的位数,右边界之外的位被丢弃,对于无符号类型,左边界空出来的位填充0。
示例代码:

unsigned char a = 0b11001100;
unsigned char result = a >> 2; // result将会是 0b00110011

7位字段(Bit-Fields)
C中的位字段是一个结构体成员,具有指定的宽度。位字段可用于紧凑地存储数据。
示例代码:

struct BitField {
    unsigned int is_enabled   : 1;
    unsigned int is_visible   : 1;
    unsigned int is_editable  : 1;
    unsigned int unused       : 5; // 填补到一个字节的剩余部分
};

struct BitField myField;
myField.is_enabled = 1;
myField.is_visible = 0;
myField.is_editable = 1;

在这个例子中,我们定义了一个位字段BitField,它使用了3个位来存储三个布尔值,并用5个未使用的位来填充剩下的空间使其成为8位(一个字节)。注意,位字段的排序和填充可能依赖平台的实现。

在嵌入式系统编程中,位操作和位字段经常被用于以下应用场景:

硬件访问和控制


嵌入式系统通常涉及直接与硬件寄存器交互。这些硬件寄存器可能用单个位或位组来控制硬件的特定功能。例如,一个寄存器的一位可能用于开启或关闭LED,另一位可能用于检测按钮是否被按下。通过位操作,程序员可以精确控制和查询这些硬件状态。
示例:

#define LED_CONTROL_REGISTER (*((volatile unsigned int*)0x12345678))

// 开启LED
LED_CONTROL_REGISTER |= (1 << LED_BIT);

// 关闭LED
LED_CONTROL_REGISTER &= ~(1 << LED_BIT);

数据压缩


当内存资源有限时,如在某些微控制器或早期计算机系统中,使用位字段可以有效地压缩数据,利用每一个二进制位来存储信息,从而最大化利用可用空间。
示例:

struct SensorFlags {
    unsigned int lowBattery     : 1;
    unsigned int sensorError    : 1;
    unsigned int transmissionOK : 1;
    // 其他状态位...
};

协议实现


许多通信协议,例如串行协议,都在消息中使用位或位组来表示不同的信息。位操作可以解析和构建符合这些协议的消息。
示例:

unsigned char message;
// 设置开始位和停止位
message |= (1 << START_BIT);
message &= ~(1 << STOP_BIT);

状态机实现


状态机经常在嵌入式系统中用于控制复杂的操作流程。使用位操作来管理状态机的各种状态可以简化代码并提高效率。
示例:

enum States {
    INIT_STATE = 0b0001,
    IDLE_STATE = 0b0010,
    RUN_STATE  = 0b0100,
    STOP_STATE = 0b1000
};

unsigned int currentState = INIT_STATE;

位掩码操作


位掩码(即一组位)可以一次性地测试、设置或清除多个位,这在设置硬件选项和特性时特别有用。
示例:

// 假设我们有一个控制寄存器
unsigned int controlReg = 0x00FF00FF;
// 假设需要清除 byte 2 和 byte 3
unsigned int mask = 0xFF00FFFF;
controlReg &= mask;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/463276.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rabbit MQ详解

写在前面,由于Rabbit MQ涉及的内容较多&#xff0c;赶在春招我个人先按照我认为重要的内容进行一定总结&#xff0c;也算是个学习笔记吧。主要参考官方文档、其他优秀文章、大模型问答。自己边学习边总结。后面有时间我会慢慢把所有内容补全&#xff0c;分享出来也是希望可以给…

软考高级:软件工程螺旋模型概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

小清新卡通人物404错误页面模板源码

小清新卡通人物404错误页面模板源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 小清新卡通人物404错误页面模板源码

uiCA模拟器和bHive benchmark的使用

概念 uiCA 基本块吞吐量预测器 github地址&#xff1a;GitHub - andreas-abel/uiCA: uops.info Code Analyzer uiCA是一个模拟器&#xff0c;可以预测基本块在最新的英特尔微体系结构上的吞吐量。除此之外&#xff0c;它还提供了代码执行的洞察。 uiCA基于来自uops.info的数…

分布式搜索引擎elasticsearch(2)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;[Domain Specific Language](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html)&#xff09;来定义查…

获取扇区航班数

1、Spark Streaming清洗服务&#xff0c;接收kafka中Topic为“task_ATC”中的数据&#xff0c;保存在MySQL中。 打开SpringBoot项目BigData-Etl-KongGuan 请认真阅读&#xff1a;在前面的“使用Spark清洗统计业务数据并保存到数据库中”任务阶段中应该已经完成了所有Topic的数…

瑞_Redis_短信登录(二)

文章目录 项目介绍1.1 项目准备1.2 基于Session实现登录流程1.2.1 发送短信验证码1.2.2 短信验证码登录、注册1.2.3 校验登录状态 1.3 实现发送短信验证码功能1.3.1 页面流程1.3.2 代码实现 1.41.51.6 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《Redis》的实战篇的…

16 stack和queue习题

最小栈 最小栈 思路 用两个栈实现&#xff0c;一个栈正常插入和删除&#xff0c;另一个栈记录当前最小元素&#xff0c;第一个栈删除的时候&#xff0c;如果和最小的栈顶元素相等&#xff0c;最小的栈也删除元素 class MinStack { public:MinStack() {}void push(int val) {…

关于使用过别人的GitHub/Gitee账号提交东西到仓库后,自己的仓库提交失败问题的解决方法

目录 引言 问题出现的原因 问题的解决方法 打开控制面板 方法一&#xff1a; 方法二&#xff1a; 进入Windows凭据管理器 结语 引言 这个问题折磨了我将近三个小时&#xff0c;为了减少有人和我一样走弯路且防止自己忘记解决方法&#xff0c;便有了这篇文章。 问题出现…

RequestResponse使用

文章目录 一、Request&Response介绍二、Request 继承体系三、Request 获取请求数据1、获取请求数据方法&#xff08;1&#xff09;、请求行&#xff08;2&#xff09;、请求头&#xff08;3&#xff09;、请求体 2、通过方式获取请求参数3、IDEA模板创建Servlet4、请求参数…

android studio设置flutter和dart的sdk配置

提示没有配置dart sdk的时候&#xff0c;其实只需要配置一下flutter的sdk就可以了&#xff0c;因为flutter的安装包里面包含了dart的sdk&#xff1a; 按照提示选中这个flutter的安装包路径就可以了&#xff1a; 并且需要开启windows的开发者开关&#xff1a;start ms-settings:…

C++/CLI介绍

什么是C++/CLI C++/CLI的链接 上图实现cli编译的obj文件和非cli编译的目标文件之间实现链接。 上图实现cli编译的obj文件和lib文件之间进行链接 上图实现cli编译的代码对非cli编译的dll的引用 C++/CLI基本语法 基本类型

【Java基础】IO流(三):字符流的FileReader(文件字符输入流)和 FileWriter(文件字节输出流)

目录 字符流 1、FileReader&#xff08;字符输入流&#xff09; 1.1、无参的read( )方法示例 ​编辑 1.2、有参的read(char[ ] buffer)方法示例 2、FileWriter&#xff08;字符输出流&#xff09; 字符流 字符流的底层其实就是字节流&#xff0c;即字符流 字节流 字符集…

mac激活pycharm,python环境安装和包安装问题

1.PyCharm到官网下载就行 地址&#xff1a;Other Versions - PyCharm (jetbrains.com) 2.MacOS 下载python环境&#xff0c;地址&#xff1a; Python Releases for macOS | Python.org 3.PyCharm环境配置&#xff1a; 4. 如果包下载不下来可以换个源试试 pip install py…

前后端分离:现代Web开发的协作模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【NTN 卫星通信】 TN和多NTN配合的应用场景

1 场景描述 此场景描述了农村环境&#xff0c;其中MNO (运营商TerrA)仅在城市附近提供本地地面覆盖&#xff0c;而MNO (SatA)提供广泛的NTN覆盖。SatA使用GSO轨道和NGSO轨道上的卫星。SatA与TerrA有漫游协议&#xff0c;允许:   所有TerrA用户的连接&#xff0c;当这些用户不…

Linux批量注释

1.注释行 1.按ctrlv进入块选择模式 &#xff0c;然后上下键选中需要注释的行 2.按shifti(也就是大写I) 然后输入// 或 # 3.按ESC键 2.取消注释行 1.按ctrlv进入块选择模式&#xff0c; 然后上下键选中需要取消注释的行 2.然后按d

【工具】一键生成动态歌词字幕

那眼神如此熟悉 让人着迷无力抗拒 一次又一次相遇 在眼前却遥不可及 命运总爱淘气 将一切都藏匿 曾有你的回忆 无痕迹 若不是心心相吸 又怎么会一步一步靠近 &#x1f3b5; 董真《思如雪》 下载LRC歌词 https://www.musicenc.com/article/50287.htmlhttp…

Word粘贴时出现“运行时错误53,文件未找到:MathPage.WLL“的解决方案

在安装完MathType后&#xff0c;打开word复制粘贴时报错“运行时错误53,文件未找到&#xff1a;MathPage.WLL” 首先确定自己电脑的位数&#xff08;这里默认32位&#xff09; 右击MathType桌面图标&#xff0c;点击“打开文件所在位置”&#xff0c; 然后分别找到MathPage.W…

【算法训练营】最近点对,纸牌,青蛙(Python实现)

最近点对 描述 给定n个二维平面上的点&#xff0c;求距离最近的一对点&#xff0c;输出他们的距离。 输入 第一行包含一个正整数n。 接下来n行&#xff0c;每行包含两个整数x,y&#xff0c;表示一个点的坐标。 输出 输出距离最近的一对点的距离&#xff0c;保留两位小数。 样例…
最新文章