我有以下bitfield结构:
struct DescriptorByte
{
unsigned short IsImmedCalc : 1;
unsigned short IsPrefix : 1;
unsigned short NoMemOp : 1;
unsigned short Size : 5;
};
我想创建一个用于保存许多DescriptorByte结构的表,所以我创建了这个:
struct OpcodeList
{
DescriptorByte ADD_8_MO;
DescriptorByte ADD_32_MO;
DescriptorByte ADD_8_OM;
DescriptorByte ADD_32_OM;
DescriptorByte ADD_8_OI = { TRUE, FALSE, TRUE, 1 + 1 };
DescriptorByte ADD_32_OI = { TRUE, FALSE, TRUE, 1 + 4 };
DescriptorByte PUSH_ES = { TRUE, FALSE, TRUE, 1 };
};
这是否与每个成员长度为1个字节的结构相同?此外,我希望能够像这样引用初始化成员:
DescriptorByte ADD_8_OI = { IsImmedCalc = true, Size = 1 };
但是视觉工作室不让我。所有这一切背后的想法是有一个DescriptorByte表,这是最好的方法吗?还有什么是最好的初始化方法?感谢。
答案 0 :(得分:2)
“这与具有每个成员长度为1个字节的结构相同吗?”
如果您不使用#pragma pack
或类似的东西,您的编译器可能会添加填充。
但是在这个特定情况下没有任何填充,所以基本上答案是肯定的。
只需将unsigned short
更改为unsigned char
,每个成员的长度为1个字节。
添加'。'在每个字段的左侧:
DescriptorByte ADD_8_OI = { .IsImmedCalc = true, .Size = 1 };
或者,只需按正确的顺序写下实际值(缺少的值将设置为0):
DescriptorByte ADD_8_OI = { true, 1 };
答案 1 :(得分:1)
编辑:发布此认为这是一个C#问题,抱歉!把它留给别人。
C#不支持位字段。但是,您仍然可以使用适当大小的单个成员变量以及各种getter属性来“模拟”该行为。
在您的示例中,您希望使用无符号的8位整数值(byte
)并封装这些位域。不用担心,您仍然可以使用struct
来完成所有这些操作,以便更轻松地进行编组和互操作。
所以,让我们带你的DescriptorByte
并重新创建你想要做的事情:
struct DescriptorByte
{
static readonly byte IsImmedCalcFlag = 0x80; // 1000 0000
static readonly byte IsPrefixFlag = 0x40; // 0100 0000
static readonly byte NoMemOpFlag = 0x20; // 0010 0000
static readonly byte FlagsBitMask = 0xE0; // 1110 0000
static readonly byte SizeBitMask = 0x1F; // 0001 1111
byte field;
public bool IsImmedCalc
{
get { return (field & IsImmedCalcFlag) > 0; }
set
{
if (value)
field = (byte)(field | IsImmedCalcFlag); // Set the bit
else
field = (byte)(field & ~IsImmedCalcFlag); // Clear the bit
}
}
public bool IsPrefix
{
get { return (field & IsPrefixFlag) > 0; }
set
{
if (value)
field = (byte)(field | IsPrefixFlag); // Set the bit
else
field = (byte)(field & ~IsPrefixFlag); // Clear the bit
}
}
public bool NoMemOp
{
get { return (field & NoMemOpFlag) > 0; }
set
{
if (value)
field = (byte)(field | NoMemOpFlag); // Set the bit
else
field = (byte)(field & ~NoMemOpFlag); // Clear the bit
}
}
public byte Size
{
get { return (byte)(field & SizeBitMask); }
set { field = (byte)((field & FlagsBitMask) | (value & SizeBitMask)); }
}
}