【问题标题】:2 bits size variable2 位大小可变
【发布时间】:2013-01-30 09:04:22
【问题描述】:

我需要定义一个结构,它的数据成员大小为 2 位和 6 位。 我应该为每个成员使用char 类型吗?或者,为了不浪费内存,我可以使用:2\:6 之类的符号吗? 我怎样才能做到这一点? 我可以为 2 位或 6 位类型定义 typedef 吗?

【问题讨论】:

  • 如何使用std::bitset<char> ??

标签: c++ size bit


【解决方案1】:

你可以使用类似的东西:

typedef struct {
    unsigned char SixBits:6;
    unsigned char TwoBits:2;
} tEightBits;

然后使用:

tEightBits eight;
eight.SixBits = 31;
eight.TwoBits = 3;

但是,老实说,除非您必须遵守应用程序外部的打包数据,或者您处于非常内存受限的情况,否则这种内存节省通常不会值得。如果不必一直使用按位和位移操作来打包和解包数据,您会发现您的代码要快得多。


另外请记住,使用除_Boolsigned intunsigned int 之外的任何类型都是实现的问题。具体来说,unsigned char 可能并不适用于所有地方。

【讨论】:

  • 我可以为 2 位或 6 位类型定义 typedef 吗?
  • 不行,你只能在结构体中这样做。
【解决方案2】:

这样的事情最好使用uint8_t。是的,使用bit fields

struct tiny_fields
{
  uint8_t twobits : 2;
  uint8_t sixbits : 6;
}

不过,我认为您不能确定编译器会将其打包成一个字节。此外,在 struct 类型的值占用的字节内,您不知道这些位是如何排序的。如果您想要更多控制权,通常最好使用显式掩码。

【讨论】:

  • +1,但我认为使用unsigned char 比使用uint8_t 更好。后者永远不能小于unsigned char,因此不会节省任何空间。它被允许根本不存在。使用uint8_t 只是静态断言CHAR_BIT == 8 的一种方式。
  • 请记住,位集/位字段会比 chars 慢。这是因为要写入位字段,您需要读取封闭字节,更新它,然后将其写回(读-修改-写循环)。不值得努力,除非你承受着极大的记忆压力。
  • @Noor,可能是因为它保证是 8 位(在支持 8 位的系统中),对于字符来说你不能说。
  • 公平地说,你几乎肯定还在到处使用&0x3f,只是它没有出现在你的源代码中:-) 当然,这仍然可能是使用它的充分理由,因为可读性对我来说很重要。
  • @paxdiablo:当然,编译器正在疯狂地屏蔽。我认为计算机科学家称该技术为“抽象”;-)
【解决方案3】:

我个人更喜欢移位运算符和一些宏而​​不是位字段,因此编译器没有“魔法”。这是嵌入式世界的惯例。

#define SET_VAL2BIT(_var, _val) ( (_var) | ((_val) & 3) )
#define SET_VAL6BIT(_var, _val) ( (_var) | (((_val) & 63)  << 2) )

#define GET_VAL2BIT(_var) ( (_val) & 3)
#define GET_VAL6BIT(_var) ( ((_var) >> 2) & 63 )

static uint8_t my_var;

<...>
SET_VAL2BIT(my_var, 1);
SET_VAL6BIT(my_var, 5);
int a = GET_VAL2BIT(my_var); /* a == 1 */
int b = GET_VAL6BIT(my_var); /* b == 5 */

【讨论】:

    猜你喜欢
    • 2013-01-04
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    相关资源
    最近更新 更多