C语言高阶技术点详解:深入理解位操作

位操作是C语言中一项强大的特性,它允许我们直接在二进制层面上操作数据。位操作在底层编程、加密、数据压缩和性能优化等领域有着广泛的应用。本文将详细探讨C语言中的位操作,结合代码案例,为你揭示背后的技术原理,帮助你更深入地理解C语言的精髓。

1. 位操作的基本概念与操作符

位操作是对数据在二进制位级别上的操作。C语言提供了一系列位操作符,包括按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移(<<)和右移(>>)。

1.1 按位与(AND)

按位与操作符&对两个操作数的每一位进行逻辑与操作。只有两个位都是1时,结果位才是1。

int a = 6; // 二进制: 110
int b = 4; // 二进制: 100
int result = a & b; // 结果: 4 (二进制: 100)

1.2 按位或(OR)

按位或操作符|对两个操作数的每一位进行逻辑或操作。只要有一个位是1,结果位就是1。

int a = 6; // 二进制: 110
int b = 4; // 二进制: 100
int result = a | b; // 结果: 6 (二进制: 110)

1.3 按位异或(XOR)

按位异或操作符^对两个操作数的每一位进行逻辑异或操作。只有两个位不相同时,结果位才是1。

int a = 6; // 二进制: 110
int b = 4; // 二进制: 100
int result = a ^ b; // 结果: 2 (二进制: 010)

1.4 按位取反(NOT)

按位取反操作符~对操作数的每一位进行取反。0变成1,1变成0。

int a = 6; // 二进制: 110
int result = ~a; // 结果: -7 (二进制: 001)

1.5 左移(Shift Left)

左移操作符<<将操作数的所有位向左移动指定的位数,右边补0。

int a = 1; // 二进制: 0001
int result = a << 2; // 结果: 4 (二进制: 0100)

1.6 右移(Shift Right)

右移操作符>>将操作数的所有位向右移动指定的位数。对于无符号数,左边补0;对于有符号数,根据符号位进行填充。

int a = 4; // 二进制: 0100
int result = a >> 2; // 结果: 1 (二进制: 0001)

2. 位操作的应用

位操作在C语言中有着广泛的应用,下面是一些常见的使用场景。

2.1 标志位的设置和清除

位可以用来表示状态或选项,通过位操作可以设置或清除特定的标志位。

#define FLAG_1 0x01 // 第1位
#define FLAG_2 0x02 // 第2位
#define FLAG_3 0x04 // 第3位unsigned char flags = 0; // 所有标志位初始为0// 设置标志位
flags |= FLAG_1; // 设置第1位
flags |= FLAG_2; // 设置第2位// 清除标志位
flags &= ~FLAG_1; // 清除第1位// 检查标志位
if (flags & FLAG_1) {// 第1位被设置
}

2.2 位掩码的使用

位掩码可以用来从数据中提取特定的位或组合。

unsigned char data = 0b10110010; // 二进制数据// 提取第3和第4位
unsigned char mask = 0b00110000; // 掩码
unsigned char result = data & mask; // 结果: 0b00110000// 检查第6位是否为1
if (data & (1 << 6)) {// 第6位为1
}

2.3 位操作的优化

位操作可以用来优化性能,例如替代乘法和除法运算。

// 使用左移和右移操作替代乘法和除法
int multiplyByTwo(int number) {return number << 1; // 相当于 number * 2
}int divideByTwo(int number) {return number >> 1; // 相当于 number / 2,注意对负数的行为不同
}

2.4 位域的使用

位域(Bit Field)允许我们以位为单位来定义结构体的成员,这样可以节省内存并提高可读性。

typedef struct {unsigned int a : 1; // 占用1位unsigned int b : 2; // 占用2位unsigned int c : 3; // 占用3位
} BitField;BitField flags = {1, 2, 3}; // 设置位域的值

3. 位操作的进阶技巧

3.1 位翻转

位翻转是指将一个数的位顺序颠倒。这可以通过一系列的位操作来实现。

unsigned char toggleBits(unsigned char n) {n = ((n & 0xF0) >> 4) | ((n & 0x0F) << 4); // 交换前四位和后四位n = ((n & 0xCC) >> 2) | ((n & 0x33) << 2); // 交换奇数位和偶数位n = ((n & 0xAA) >> 1) | ((n & 0x55) << 1); // 交换相邻位return n;
}

3.2 位计数

位计数是指计算一个数中1的个数。这可以通过Brian Kernighan算法来实现,该算法的时间复杂度接近O(log n)。

int countBits(unsigned int n) {int count = 0;while (n) {n &= (n - 1); // 清除最低位的1count++;}return count;
}

3.3 位压缩

位压缩是指将多个数据项压缩到一个数中。例如,如果我们有8个布尔值,我们可以将它们存储在一个字节中。

typedef struct {unsigned char flag1 : 1;unsigned char flag2 : 1;unsigned char flag3 : 1;unsigned char flag4 : 1;unsigned char flag5 : 1;unsigned char flag6 : 1;unsigned char flag7 : 1;unsigned char flag8 : 1;
} CompressedFlags;CompressedFlags flags = {1, 0, 1, 0, 1, 0, 1, 0}; // 压缩8个布尔值到一个字节

4. 结语

通过本文的深入探讨,我们揭示了C语言中位操作的强大功能和背后的技术原理。位操作在底层编程和性能优化中扮演着重要角色,能够帮助我们编写更加高效和精炼的代码。理解和掌握这些技术点,不仅能够提高编程效率,还能够更好地理解计算机的工作原理。希望本文能够为你的C语言学习之旅提供有力的支持,激发你对技术深入探索的热情。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用cgroup对pgsql进行分库资源限制

系统&#xff1a;Centos7 pg版本&#xff1a;14.11 自建pgsql14中有很多个库&#xff0c;一个库对应一个租户&#xff0c;偶尔会出现单个租户执行慢sql影响全局的问题&#xff0c;目前官方也没有比较合适的处理方案或者插件 解决方案&#xff1a; 因为pgsql是多进程应用&…

DB-GPT-PaperReading

DB-GPT: Empowering Database Interactions with Private Large Language Models 1. 基本介绍 DB-GPT 旨在理解自然语言查询,提供上下文感知响应,并生成高精度的复杂 SQL 查询,使其成为从新手到专家的用户不可或缺的工具。DB-GPT 的核心创新在于其私有 LLM 技术,该技术在…

FL Studio 2024 发布,添加 FL Cloud 插件、AI 等功能

作为今年最受期待的音乐制作 DAW 更新之一&#xff0c;FL Studio 2024发布引入了新功能&#xff0c;同时采用了新的命名方式&#xff0c;从现在起将把发布年份纳入其名称中。DAW 的新增功能包括在 FL Cloud 中添加插件、AI 驱动的音乐创作工具和 FL Studio 的新效果。 FL Cloud…

ThinkPHP定时任务是怎样实现的?

接到一个需求&#xff1a;定时检查设备信息&#xff0c;2分钟没有心跳的机器&#xff0c;推送消息给相关人员&#xff0c;用thinkphp5框架&#xff0c;利用框架自带的任务功能与crontab配合来完成定时任务。 第一步&#xff1a;分析需求 先写获取设备信息&#xff0c;2分钟之…

力扣双指针算法题目:快乐数

目录 1.题目 2.思路解析 3.代码展示 1.题目 . - 力扣&#xff08;LeetCode&#xff09; 2.思路解析 题目意思是将一个正整数上面的每一位拿出来&#xff0c;然后分别求平方&#xff0c;最后将这些数字的平方求和得到一个数字&#xff0c;如此循环&#xff0c;如果在此循环中…

【做一道算一道】和为 K 的子数组

给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;nums [1,2,3],…

前端面试题8

基础知识 解释一下什么是跨域问题&#xff0c;以及如何解决&#xff1f; 跨域问题是由于浏览器的同源策略限制了从一个源加载的网页脚本访问另一个源的数据。解决方法包括使用JSONP、CORS&#xff08;跨源资源共享&#xff09;、设置代理服务器等。 描述一下事件冒泡和事件捕获…

Flutter-实现悬浮分组列表

在本篇博客中&#xff0c;我们将介绍如何使用 Flutter 实现一个带有分组列表的应用程序。我们将通过 CustomScrollView 和 Sliver 组件来实现该功能。 需求 我们需要实现一个分组列表&#xff0c;分组包含固定的标题和若干个列表项。具体分组如下&#xff1a; 水果动物职业菜…

BigDecimal(double)和BigDecimal(String)有什么区别?BigDecimal如何精确计数?

BigDecimal(double)和BigDecimal(String)的区别 double是不精确的&#xff0c;所以使用一个不精确的数字来创建BigDecimal&#xff0c;得到的数字也是不精确的。如0.1这个数字&#xff0c;double只能表示他的近似值。所以&#xff0c;当我们使用new BigDecimal(0.1)创建一个Bi…

【Academy】DOM-based vulnerabilities 基于DOM的漏洞

基于DOM的漏洞 1.基于DOM的漏洞2.什么是DOM&#xff1f;3.污染流漏洞3.1什么是污染流&#xff1f;源接收器 3.2常见源 4.哪些接收器会导致基于DOM的漏洞&#xff1f;基于DOM的开放重定向基于DOM的cookie操作基于DOM的JavaScript注入基于DOM的文档域操作基于DOM的WebSocket-URL中…

golang验证Etherscan上的智能合约

文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口&#xff08;最重要的步骤&#xff09; golan…

归并排序的实现(递归与非递归)

概念 基本思想&#xff1a;归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使…

揭秘Conda:Python开发者必备的包管理神器

conda 简介 Conda 是一个开源的包管理系统和环境管理系统&#xff0c;用于安装和管理软件包以及创建和维护不同的软件环境。 它最初是为 Python 语言设计的&#xff0c;但现在已经支持多种编程语言&#xff0c;包括 R、Ruby、Lua、Scala 等。 1、Anaconda&#xff1a;是一个…

GPIO配置-PIN_Speed的理解

在使用STM32的GPIO 口配置时&#xff0c;经常会疑惑应该选用什么样的配置模式&#xff0c;本文谈谈对pin_speed的理解。 根据数据手册可得&#xff0c;STM32提供10MHz,2MHz和50MHz三种输出速度的配置&#xff0c;三种配置的应用场景是怎么样的&#xff1f;。 1.为什么要配置引…

Ubuntu Linux 22 云服务器配置备忘

登录云服务器控制台&#xff0c;开放端口&#xff1a;8888&#xff0c;9999&#xff0c;6666&#xff0c;5555&#xff0c;80&#xff0c;443 设置子域名指向IP ssh rootxx.domain.name 更新系统&#xff1a; # apt update && apt upgrade -y 安装基本工具&#x…

[护网训练]原创应急响应靶机整理集合

前言 目前已经出了很多应急响应靶机了&#xff0c;有意愿的时间&#xff0c;或者正在准备国护的师傅&#xff0c;可以尝试着做一做已知的应急响应靶机。 关于后期&#xff1a; 后期的应急响应会偏向拓扑化&#xff0c;不再是单单一台机器&#xff0c;也会慢慢完善整体制度。…

论文辅助笔记:ST-LLM

1 时间嵌入 2 PFA&#xff08;Partial Frozen Architecture&#xff09; 3 ST_LLM 3.1 初始化 3.2 forward

强化学习中的Double DQN、Dueling DQN和PER DQN算法详解及实战

1. 深度Q网络&#xff08;DQN&#xff09;回顾 DQN通过神经网络近似状态-动作值函数&#xff08;Q函数&#xff09;&#xff0c;在训练过程中使用经验回放&#xff08;Experience Replay&#xff09;和固定目标网络&#xff08;Fixed Target Network&#xff09;来稳定训练过程…

【Scrapy】 深入了解 Scrapy 下载中间件的 process_exception 方法

准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 &#x1f3b5; 陈慧娴《傻女》 Scrapy 是…

科大讯飞-群聊对话角色要素提取:不微调范式模拟官网评分

不微调范式模拟官网评分 step1: 模型api配置及加载测试step2: 数据加载与数据分析&#xff1a;测试集分析:step3: prompt设计:step4 :大模型推理&#xff1a;step 5: 结果评分测试&#xff1a;评分细则&#xff1a;评估指标 参考&#xff1a; 比赛说明&#xff1a; #AI夏令营 #…