2011-09-02 75 views
6

在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. 大于等于4个字节的大小,还是大小为1个字节?
  3. 变量被视为1(或3)位如图所示,或按照'unsigned char'被视为每个字节?
  4. 有没有将位组合到一个集中的字节的方法?例如:

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

您正在寻找的名称是bitfields –

+0

我想我应该问:您使用的是C还是C++?如果C++,你是否在非POD类中使用它?我有一种感觉,C++将位域限制为POD结构类型。 –

+0

C++。我包括btoh,所以我知道两个规格的差异(也扩大了适用的解决方案)。是的,我在课堂上使用它(虽然现在是设计阶段),但如果它只能用作结构,我可以轻松地转换。它为一个GIF图像加载程序。 – SSight3

回答

8

实际称为上述技术是什么?

Bitfields。你只能使用intsigned,unsigned或其他)作为“类型”,而不是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 

注意,这里使用线程时与位域问题,例如。每个位域都不能单独访问,所以如果您尝试使用互斥锁来保护每个位域,则可能会出现错误。此外,标准中没有明确规定字段的排列顺序。出于这个原因,许多人更喜欢使用位运算符来手动实现位域。

是否有一篇文章更深入地讨论了这个话题?

并不多。当你开始Google时,你会得到前几个关于你所能找到的所有内容。他们不是一个广泛使用的构造。你会很乐意挑选标准来弄清楚它们是如何工作的,这样你就不会被奇怪的边缘情况所困扰。我无法确切地告诉你他们指定的标准在哪里。

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

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

+0

用于使用int(有符号,无符号或其他)作为“类型”的+1,不是char.' – Sadique

+0

几乎唯一的要求是在C99 6.7.2.1/10中规定的。没有太多要求。 –

+0

感谢您提供非常深入的信息。 – SSight3

5

这些是位字段

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

+0

感谢您的贡献。 – SSight3