位设置问题

时间:2011-09-02 22:30:52

标签: c++ c bit-manipulation

在C或C ++中,显然可以限制变量的位数,例如:

unsigned char A:1;
unsigned char B:3;

我不熟悉它的具体工作方式,所以有很多问题:

如果我有一个包含以下变量的类:

unsigned char A:1;
unsigned char B:3;
unsigned char C:1;
unsigned char D:3;
  1. 上面实际调用的技术是什么?
  2. 大小超过四个字节,还是一个字节大小?
  3. 变量被视为1(或3)位,如图所示,还是根据'unsigned char',被视为每个字节?
  4. 有没有将这些位组合成一个集中字节?例如:
  5. unsigned char MainByte;
    unsigned char A:1; //Can this be made to point at the first bit in MainByte?
    unsigned char B:3; //Etc etc
    unsigned char C:1;
    unsigned char D:3;
    
    1. 是否有更深入介绍此主题的文章?
    2. 如果'A:1'被视为整个字节,它的点/紫色是什么?
    3. 随意提及任何其他注意事项(如编译器限制或其他限制)。

      谢谢。

2 个答案:

答案 0 :(得分:8)

  

上面实际调用的技术是什么?

位字段。您只应使用intsignedunsigned或其他方式)作为“类型”,而不是char

  

大小是四个字节的大小,还是一个大小的字节?

都不是。它可能是sizeof(int),因为编译器会生成一个字大小的对象。但是,实际的位域将存储在一个字节内。它只会浪费一些空间。

  

变量是被视为1(或3)位,如图所示,还是按照'unsigned char',被视为每个字节?

它们仅代表指定的位,并将尽可能紧密地打包。

  

有没有将这些位组合成一个集中字节?例如:

使用union

struct bits {
  unsigned A:1;
  unsigned B:3;
  unsigned C:1;
  unsigned D:3;
};

union SplitByte {
  struct bits Bits;
  unsigned char Byte[sizeof(struct bits)];
  /* the array is a trick so the two fields
     are guaranteed to be the same size and
     thus be aligned on the same boundary */
} SplitByteObj;

// access the byte
SplitByteObj.Byte[0]

// access a bitfield
SplitByteObj.Bits.B

请注意,位域存在问题,例如使用线程时。无法单独访问每个位域,因此如果您尝试使用互斥锁来保护每个位域,则可能会出错。此外,标准没有明确规定字段布局的顺序。由于这个原因,许多人更喜欢使用按位运算符来手动实现位域。

  

是否有更深入介绍此主题的文章?

并不多。当你使用谷歌时,你会得到的最初几个就是你所能找到的。它们不是广泛使用的构造。你最好挑选标准来弄清楚它们是如何工作的,这样你就不会被一个奇怪的边缘情况所困扰。我无法确切地告诉你它们在标准中的确切位置。

  

如果'A:1'被视为整个字节,它的点/紫色是什么?

不是,但我已经解决了这个问题。

答案 1 :(得分:5)

这些是位字段

这些字段在内存中的排列方式的细节主要是实现定义的。通常,您会发现编译器以某种方式打包它们。但是可能需要考虑各种对齐问题。