在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;
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;
随意提及任何其他注意事项(如编译器限制或其他限制)。
谢谢。
答案 0 :(得分:8)
上面实际调用的技术是什么?
位字段。您只应使用int
(signed
,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
请注意,位域存在问题,例如使用线程时。无法单独访问每个位域,因此如果您尝试使用互斥锁来保护每个位域,则可能会出错。此外,标准没有明确规定字段布局的顺序。由于这个原因,许多人更喜欢使用按位运算符来手动实现位域。
是否有更深入介绍此主题的文章?
并不多。当你使用谷歌时,你会得到的最初几个就是你所能找到的。它们不是广泛使用的构造。你最好挑选标准来弄清楚它们是如何工作的,这样你就不会被一个奇怪的边缘情况所困扰。我无法确切地告诉你它们在标准中的确切位置。
如果'A:1'被视为整个字节,它的点/紫色是什么?
不是,但我已经解决了这个问题。
答案 1 :(得分:5)
这些是位字段。
这些字段在内存中的排列方式的细节主要是实现定义的。通常,您会发现编译器以某种方式打包它们。但是可能需要考虑各种对齐问题。