是否有一种方法可以改变变量在内存中的存储方式(位大小)
Is there a way to change how a variable is stored in memory (bit sizes)?
假设我有以下数据结构(伪代码):
struct
{
uint8 id;
bool failure;
uint8 value;
}
现在,假设我希望数据以以下方式存储在内存中:
bit 7-6: id第5位:失败Bit 4-0: value
在C/c++/Visual Studio中是否有这样的方法?我知道你可以用Ada来做,但这并不意味着什么。
编辑:抱歉不清楚,我确实需要一个特定的内存布局。此结构将用于通过串行通道发送的消息,它需要符合接口规范
您可以使用C位域:
struct
{
uint8 id : 2;
bool failure : 1;
uint8 value : 5;
};
然而,尽管可以减少结构体*使用的内存量,但这并不能保证任何特定的内存布局;为每个字段分配的特定位取决于编译器和/或平台ABI。如果您需要为特定字段分配特定的位索引,则需要手动打包和解包。或者,如果您的代码不需要可移植,您可以查看编译器如何打包位字段,并相应地对结构体的成员进行排序。
* - C标准对位域布局的限制很少,c++更少。通常这将导致更少的内存使用,但如果编译器决定它将使用的最小位字段分配单元是32位字段或其他东西,那么大小实际上可能会增加。参见ISO/IEC 9899:1999 (E)§6.7.2.1/10
struct
{
int id :2;
bool failure:1;
int value :5;
}
对于原始数据的答案,您基本上将数据放入uint8_t
并使用位掩码和位移位来提取数据,一个示例实现可以是:
class MyData
{
private:
uint8_t data;
public:
MyData() : data(0) {}
MyData(uint8_t id, bool failure, uint8_t value) : data(0)
{
Id(id);
Failure(failure);
Value(value);
}
uint8_t Id()
{
return (data>>6);
}
void Id(uint8_t id)
{
data &= 0x3F;
data |= ((id&0x3)<<6);
}
bool Failure()
{
return (data & 0x20);
}
void Failure(bool failure)
{
if(failure)
{
data |= 0x20;
}
else
{
data &= 0xDF;
}
}
uint8_t Value()
{
return (data & 0x0F);
}
void Value(uint8_t val)
{
data &= 0xF0;
data|=(val&0xF);
}
};
让我们以Id为例,你想要设置两个最高阶位,位掩码这是0xC0。当然,你必须把它的6位移下来得到实际的值,否则你会得到128 iso 2。我去掉了掩码,因为实际上没有高阶比特,而比特滤波去掉了低阶比特。
设置它是类似的,你想要覆盖之前的数据,这是指令1 (ox3F==00111111b
), and操作符清除掩码中为0的部分,并且不触及其他位。指令2使用or运算符将(先前清除的)高阶位设置为新值,而保留原始值,因为低阶位是0和a|0==a
。
其他部分是类似的,希望这对你的方式有帮助... .
总结起来,检索是"应用掩码和位移位",存储是"使用&并使用"|"存储位。当然,一旦你传递多字节值,事情就变得更加复杂了(你必须考虑到字节顺序)。
这应该可以使用位字段。在这种特殊情况下,c++代码将是:
struct
{
uint8 value : 5; // bits 0-4
bool failure : 1; // bit 5
uint8 id : 2; // bit 6-7
};
注意:一定要检查编译器文档,因为位排序和内存填充可能会影响可移植性。请参见http://en.wikipedia.org/wiki/Bit_field获取更多信息或google获取c++位字段。
有一些特定于平台的方法可以使struct以这种方式打包。如果你想遵循规范,你必须手动打包到uint8缓冲区或类似的东西。编译器将尊重其他建议的解决方案中字段的大小,但可以选择任何方式将它们打包到结构体中。例如,它可以在结构体的字段之间放置未使用的填充,以实现速度优化。
- 将字符串存储在c++中的稳定内存中
- 类型总是使用其大小存储在内存中吗
- 使用无符号字符数组有效存储内存
- 具有内存顺序的原子负载存储
- CertGetCertificateChain 具有支持的内存存储和证书信任列表
- 为什么 bool 和 _Bool 如果它们在内存中占用 1 个字节,它们只能存储 0 或 1
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 存储在哪个内存段(代码/数据段)类(员工)中?
- 可用存储空间会消耗更多剩余内存吗?
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 将数据存储在内存中以供以后访问
- 英特尔将指令存储在重叠的内存区域
- 关于矢量内存存储
- 如何使一个线程中的内存存储"promptly"在其他线程中可见?
- c++中用于常量数据的内存存储
- 内存存储可以在 OoOE 处理器中真正重新排序吗?
- 动态分配的内存存储说明
- 在 std::vector 中存储指针会破坏连续内存存储的优势
- #定义指令内存存储
- 跨语言的内存存储