【C语言】16 位的值,通过几种不同的方式将其拆分为高 8 位和低 8 位

当我们想要将一个16位的 Register_Value 拆分成高8位和低8位,并存储到 Send_Data_Uart5 数组中时,有几种常见的方法可以实现。让我们逐一优化和详细分析每种方法:

方法 1: 使用位移和位掩码(常用方法)

Send_Data_Uart5[data_index++] = Register_Value >> 8;       // 提取高8位  
Send_Data_Uart5[data_index++] = Register_Value & 0xFF;     // 提取低8位

这种方法利用位移操作 >> 和按位与操作 &,分别提取出 Register_Value 的高8位和低8位,并将它们存储到 Send_Data_Uart5 数组中。这是最直观和常见的方式,适用于大多数情况。

方法1详解

详细解释如何将一个 16 位的 Register_Value 拆分为高 8 位和低 8 位,并存储在 Send_Data_Uart5 数组中

  1. 数据类型与位操作

    uint16_t Register_Value:Register_Value 是一个 16 位的无符号整数。在内存中,它通常占用两个字节(16位),取值范围是从 0 到 65535(即 2^16 - 1)。

  2. 拆分 16 位整数

    要将 Register_Value 拆分为高 8 位和低 8 位,我们使用位操作。

    • 高 8 位:高 8 位是 Register_Value 的最高位字节。我们通过右移运算符 >> 将 Register_Value 向右移动 8 位,这样原来的高 8 位就移到了最低 8 位的位置。这个操作得到的结果就是 Register_Value 的高 8 位。

      Send_Data_Uart5[data_index++] = Register_Value >> 8;
      
    • 低 8 位:低 8 位是 Register_Value 的最低位字节。我们使用位与运算符 & 和掩码 0xFF(二进制 11111111)来保留 Register_Value 的最低 8 位,其余高位清零。

      Send_Data_Uart5[data_index++] = Register_Value & 0xFF;
      
  3. 示例

    假设 Register_Value 的十六进制值为 0x1234(在十进制中是 4660):

    • 高 8 位是 0x12(十进制 18)。
    • 低 8 位是 0x34(十进制 52)。

    执行上述代码后:

    • Send_Data_Uart5[data_index++] 将存储 0x12,然后 data_index 自增。
    • Send_Data_Uart5[data_index++] 将存储 0x34,然后 data_index 再次自增。

    最终,Send_Data_Uart5 数组中将包含 0x120x34,分别表示 Register_Value 的高 8 位和低 8 位。

这种方法简单直观,适合大多数情况下将 16 位整数拆分为字节,并存储到数组中。

方法 2: 使用指针和强制类型转换(不推荐)

uint8_t *pValue = (uint8_t *)&Register_Value;  
Send_Data_Uart5[data_index++] = *pValue++; // 提取高8位  
Send_Data_Uart5[data_index++] = *pValue;   // 提取低8位

这种方法通过将 Register_Value 的地址强制转换为 uint8_t* 类型的指针,逐个访问其字节。然而,它依赖于内存对齐和硬件平台的特性,不推荐在跨平台或移植性要求高的情况下使用。

方法 3: 使用联合体(union)

typedef union {uint16_t value;struct {uint8_t low_byte;uint8_t high_byte;} bytes;
} RegisterUnion;RegisterUnion ru = { .value = Register_Value };
Send_Data_Uart5[data_index++] = ru.bytes.high_byte; // 提取高8位  
Send_Data_Uart5[data_index++] = ru.bytes.low_byte;  // 提取低8位

这种方法定义了一个联合体 RegisterUnion,通过共享内存空间直接访问 Register_Value 的高8位和低8位。这种做法更高级,通常用于复杂数据结构的处理。

方法 4: 使用内联函数或宏(为了代码重用)

// 宏定义
#define EXTRACT_HIGH_BYTE(x) ((uint8_t)((x) >> 8))
#define EXTRACT_LOW_BYTE(x)  ((uint8_t)((x) & 0xFF))// 使用宏
Send_Data_Uart5[data_index++] = EXTRACT_HIGH_BYTE(Register_Value); // 提取高8位  
Send_Data_Uart5[data_index++] = EXTRACT_LOW_BYTE(Register_Value);  // 提取低8位  // 或者内联函数(如果编译器支持)
static inline uint8_t extract_high_byte(uint16_t value) {return (uint8_t)(value >> 8);
}static inline uint8_t extract_low_byte(uint16_t value) {return (uint8_t)(value & 0xFF);
}// 使用内联函数
Send_Data_Uart5[data_index++] = extract_high_byte(Register_Value); // 提取高8位  
Send_Data_Uart5[data_index++] = extract_low_byte(Register_Value);  // 提取低8位

这种方法定义了宏或内联函数来封装提取高8位和低8位的操作,以提高代码的重用性和可读性。它们在需要频繁进行这类操作的情况下特别有用。

方法 5: 使用整数除法和取模运算的方式(易于理解)

Send_Data_Uart5[data_index++] = Register_Value / 256; // 提取高8位
Send_Data_Uart5[data_index++] = Register_Value % 256; // 提取低8位

这种方法首先通过整数除法 Register_Value / 256 提取出 Register_Value 的高8位,并将结果存储到 Send_Data_Uart5 数组中。然后通过取模运算 Register_Value % 256 提取出 Register_Value 的低8位,并将结果存储到 Send_Data_Uart5 数组中。

总结

在实际应用中,通常使用方法 1(位移和位掩码)是最常见的选择,因为它简单、直观,并且不依赖于特定的硬件或编译器特性。方法 3(联合体)适用于需要处理复杂数据结构或需要同时访问多个字段的情况。方法 4(内联函数或宏)适用于需要提高代码重用性和可读性的场景。方法 2(指针和强制类型转换)虽然有效,但不推荐,因为它可能会引入平台依赖性和对齐问题。

选择合适的方法取决于具体的需求和项目的技术要求,每种方法都有其优缺点需要综合考虑。

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

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

相关文章

Erlang 在处理高并发实时通信场景时,相比其他编程语言有哪些独特的优势和局限性?

Erlang 在处理高并发实时通信场景时具有以下独特的优势: 轻量级进程模型:Erlang 使用轻量级进程模型,每个 Erlang 进程占用非常少的内存,并且可以创建数百万个进程,使得系统可以支持大规模的并发连接。 纯函数式语言&…

最热门的智能猫砂盆好不好用?这期统统告诉你!

身为上班族的我们,常常被工作和出差填满日程。忘记给猫咪铲屎也不是一次两次了。但我们必须意识到,不及时清理猫砂盆不仅会让猫咪感到不适,还可能引发泌尿系统感染、皮肤疾病等健康问题。为了解决这个问题,越来越多的铲屎官开始将…

快速上手golang(持续更新)

由于项目需要,我不得不快速掌握go语言来帮助我进行项目的开发。时间紧迫到我来不及去了解语言的特性就直接项目上手了。我决定就先熟悉一个主流的go框架和go语言的一些日常用法,之后就得滑着这只破船摇摇晃晃上路了。 1 基础命令 就说几个用的多的&…

【Linux】使用信号进行进程间通信

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ ​ 实现原理&a…

[机器学习]-2 经典机器学习算法

一 线性模型 线性模型是机器学习中最基本和最常用的一类模型,假设输出变量是输入变量的线性组合。线性模型在许多实际应用中表现良好,并且为更复杂的模型(如非线性模型、深度学习模型)奠定了理论基础;优点是简单易懂&…

江苏隆昌化工上线隆道平台 采购管理迎来全面升级

当前,传统产业与数字产业深度加速融合,大数据、云计算、人工智能等新技术推动产业深刻变革,能源化工行业迎来战略转型加速期。数字化转型已成为能源化工企业提升运营效率、控制运营成本、提高产品质量、打造竞争优势的强大引擎。为实现传统采…

在C#中使用事务

文章目录 一、概述1、事务ACID特性2、.NET开发者用到的5种事务机制:二、数据库事务1、不同数据库的事务规则2、数据库事务的优势和限制三、ADO.Net事务四、System.EnterpriseServices自动事务处理五、System.Transactions事务1、显式事务(Explicit Transaction)2、Transacti…

数据库管理-第213期 HaloDB-Oracle兼容性测试03(20240625)

数据库管理213期 2024-06-25 数据库管理-第213期 HaloDB-Oracle兼容性测试03(20240625)1 索引1.1 B-Tree索引1.2 Hash索引1.3 复合索引1.4 唯一索引1.5 表达式索引1.6 部分索引 2 视图3 表连接3.1 内连接3.2 左/右外连接3.3 全连接清理环境: …

Linux内核测试技术

Linux 内核是Linux操作系统的核心部分,负责管理硬件资源和提供系统调用接口。随着 Linux 内核的不断发展和更新,其复杂性和代码规模也在不断增加。因此,确保内核的稳定性和可靠性变得尤为重要。内核测试技术是实现这一目标的关键手段。本文将…

css中定义鼠标指针样式的属性cursor

在CSS中,cursor 属性用于定义鼠标指针在元素上移动时的样式。它允许你改变默认的鼠标指针样式,以提供关于用户可以进行哪些操作的视觉反馈。 以下是cursor属性的一些常见值和用法: 默认值:auto 这是大多数元素的默认设置。浏览器…

学懂C#编程:常用高级技术——学会C#多线程开发(一)

多线程基本概念 在C#中,多线程允许你同时执行多个代码路径。每个线程代表一个独立的执行流,操作系统可以在不同的处理器核心上并行执行这些线程,或者在单个核心上通过时间分片来模拟并行执行。 关键概念: Thread:代…

iptables配置NAT实现端口转发

加载防火墙的内核模块 modprobe ip_tables modprobe ip_nat_ftp modprobe ip_conntrack 1.开启路由转发功能 echo net.ipv4.ip_forward 1 >> /etc/sysctl.conf sysctl -p2、将本地的端口转发到本机端口 将本机的 7777 端口转发到 6666 端口。 iptables -t nat -A PR…

面试题:HTTP的body是二进制还是文本

实际上,HTTP的body可以是二进制数据,也可以是文本。HTTP协议本身不对body内容的格式做限制,具体格式取决于Content-Type头字段的定义。 文本数据: 当Content-Type头字段指定为文本类型时(如text/plain、text/html、ap…

C# Winform 开源UI库

WinForms,作为微软.NET框架下的一个桌面应用程序开发工具,自1999年首次亮相以来,已经走过了二十多年的发展历程。它以其简单直观的拖拽式界面设计和丰富的控件库,成为了大众喜爱的入门学习编程工具。由于它是比较基础的开发工具&a…

技术发展下的前端功能扩展与后端计算压力的减少

随着Web技术的迅猛发展,越来越多的计算和数据处理功能正逐渐从后端转移到前端。这一转变不仅提升了用户体验,还显著减少了后端服务器的计算压力。本文将探讨这一趋势的背景、技术实现及其带来的优势和挑战。 技术发展背景 传统的Web应用架构以服务器为…

Windows下如何实现微信多开/分身

新建文本文档 把下面的脚本复制到文本文档中 echo offstart "" "C:\Program Files\Tencent\WeChat\WeChat.exe" start "" "C:\Program Files\Tencent\WeChat\WeChat.exe"exit把wechat.exe的路径替换成你自已的路径 想多开几个就复制…

如何写好AI绘画提示词?保姆级教程来了!

前言 提示词编辑是一个结构化的过程,用能被人类解释和理解的词语来描述图像,也就是告诉人工智能模型应该怎么绘制图片。 生成优质图像的秘诀 1.提示词要想编辑好,包括修饰词和好的句子结构,首先你要了解所有的修饰词类型。 2.St…

探索Perl中哈希的奥秘:创建与使用指南

探索Perl中哈希的奥秘:创建与使用指南 引言 Perl,这门被誉为“程序员的瑞士军刀”的语言,以其在文本处理和系统管理中的卓越性能而闻名。在Perl的世界里,哈希(Hash)扮演着至关重要的角色,它提…

SAP的RFID

射频识别 (RFID) 避免了条码扫描的局限性,条码扫描需要对每个条码进行视线访问,并且一次只能用于扫描一个项目。 一次扫描一个标签可能会令人厌烦和压力大,这会增加人为错误的机会。相反,RFID 标签不需要直…