首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法改变变量在内存中的存储方式(位大小)?

有没有办法改变变量在内存中的存储方式(位大小)?
EN

Stack Overflow用户
提问于 2011-07-12 03:12:39
回答 5查看 206关注 0票数 3

假设我有以下数据结构(伪代码):

代码语言:javascript
运行
复制
struct
{
  uint8  id;
  bool   failure;
  uint8  value;
}  

现在假设我想以以下方式将数据存储在内存中:

位7-6: id位5:故障位4-0:值

在C/C++/Visual Studio中有没有办法做到这一点?我知道你可以在Ada中做到这一点,但这并不意味着什么。

编辑:很抱歉说得不清楚,我确实需要在内存中有一个特殊的布局。此结构将用于通过串行通道发送的消息,并且它需要符合接口规范

EN

回答 5

Stack Overflow用户

发布于 2011-07-12 03:15:21

您可以使用C位域:

代码语言:javascript
运行
复制
struct
{
  uint8 id : 2;
  bool failure : 1;
  uint8 value : 5;
};

然而,尽管这可能会减少struct*使用的内存量,但这并不能保证任何特定的内存布局;分配给每个字段的特定位将取决于您的编译器和/或平台ABI。如果您需要为特定字段分配特定的位索引,则需要手动打包和解包。或者,如果您的代码不需要是可移植的,您可以查看编译器如何打包位字段,并相应地对结构的成员进行排序。

*-C标准对位域的布局限制很少,C++的限制更少。通常它会减少内存使用量,但是如果编译器决定它要使用的最小位域分配单元是32位字段之类的,那么大小实际上可能会增加。参见ISO/IEC 9899:1999 (E)§6.7.2.1/10

票数 7
EN

Stack Overflow用户

发布于 2011-07-12 03:14:32

代码语言:javascript
运行
复制
struct
{
  int  id     :2;
  bool failure:1;
  int  value  :5;
} 
票数 3
EN

Stack Overflow用户

发布于 2011-07-12 03:57:08

对于原始数据答案,您实际上将数据放在uint8_t中,并使用位掩码和位移位来提取数据,一个示例实现可以是:

代码语言:javascript
运行
复制
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位才能得到实际值,否则你会得到128iso 2。我丢弃了掩码,因为实际上没有高位,bithsift删除了低位。

设置它是类似的,你想覆盖之前的数据,这是指令一(ox3F==00111111b),and运算符会清除掩码中为0的部分,而不接触其他位。指令2使用or运算符将(先前清除的)高阶位设置为新值,并保持原始位不变,因为低阶位是0和a|0==a

其他部分都是相似的,希望这对你有所帮助。。

综上所述,检索是“应用掩码和位移位”,存储是“用&清除位,用|存储位”。当然,一旦传递了多字节值,事情就会变得更加复杂(您必须考虑字节顺序)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6655197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档