c - 将 n 字节整数拆分为单个字节的便携式方法
问题描述
问题很简单:取一个 32 位或 64 位整数并将其拆分以通过(通常)1 字节接口(如 uart、spi 或 i2c)发送。
为此,我可以轻松地使用位掩码和移位来获得我想要的。但是,我希望它是可移植的,可以在大端和小端上工作,但也使它适用于不丢弃位但通过进位旋转的平台(屏蔽可以去除多余的位,对吗?)。
示例代码:
uint32_t value;
uint8_t buffer[4];
buffer[0] = (value >> 24) & 0xFF;
buffer[1] = (value >> 16) & 0xFF;
buffer[2] = (value >> 8) & 0xFF;
buffer[3] = value & 0xFF;
我想保证这适用于任何支持 32 位整数或更多的平台。我不知道这是否正确。
解决方案
您提供的代码是最便携的方式。您将一个 32 位宽度的无符号整数值转换为一个正好为 8 位宽度的无符号整数值数组。数组中的结果字节按buffer
大端顺序排列。
不需要掩蔽。从C11 6.5.7p5 开始:
E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 具有无符号类型或 E1 具有
有符号类型和非负值,则结果的值是
E1 / 2^E2 的商的整数部分。
并且转换为具有 8 位宽度的整数(到值)等于屏蔽 8 位。所以(result >> 24) & 0xff
等于(uint8_t)(result >> 24)
(值)。当您分配给uint8_t
变量时,不需要屏蔽。无论如何,我会安全地假设它会被一个理智的编译器优化出来。
我可以建议看一下我记得的一个实现,我猜它已经以一种非常安全的方式实现了所有可能的拆分和组合固定宽度整数的变体,从字节和返回到 64 位,即gpsd 位.h。
推荐阅读
- c++ - 如何手动创建将在析构函数中阻塞的未来
- python - 从张量流模型中获取预测
- javascript - Polymer 3.x、ajax 请求(到端口 8081)和 PHP 一起开发
- scala - 从 Scala 启动的进程终止,但 Scala 永远等待它的终止
- c# - 如何使用大型数据集最小化运行时间(从 93,773 个对象列表中列出唯一对象)
- go - syscall.Errno 中的字符串函数
- javascript - 如何使用输入标签中输入的颜色将背景颜色更改为线性渐变并在单击 GO 按钮后混合?
- android - 如何在 Android、Rx 中为 HTTP 204 No Content 制作测试代码
- bash - 如何确定使用哪个 .bash_profile .profile .bashrc .zshrc?
- geometry - 使用 Boost Geometry 的地理坐标没有交叉区域