位字段的哪一端是最高有效位? 我正在使用VisualStudio 2008编写Windows XP/ Vista / 7的C++应用程序。我的一些结构使用位字段,如示例所示 typedef struct myStruct_tag { BYTE myVar1; WORD myVar2; WORD myVar3; union { struct { BYTE :1; BYTE field1 :1; BYTE field2 :1; BYTE reserved :5; } myBitField; BYTE myVar4; }; BYTE myVar5; BYTE myVar6; } myStruct_t;

位字段的哪一端是最高有效位? 我正在使用VisualStudio 2008编写Windows XP/ Vista / 7的C++应用程序。我的一些结构使用位字段,如示例所示 typedef struct myStruct_tag { BYTE myVar1; WORD myVar2; WORD myVar3; union { struct { BYTE :1; BYTE field1 :1; BYTE field2 :1; BYTE reserved :5; } myBitField; BYTE myVar4; }; BYTE myVar5; BYTE myVar6; } myStruct_t;,c,windows,visual-studio-2008,bit-fields,C,Windows,Visual Studio 2008,Bit Fields,字段的哪一端是最重要的位?如果您询问myBitField中的哪些位存储在内存中字节的哪些位中,这是C标准明确未定义的。你必须通过实验来学习。如果您正在做一些实际重要的事情,那么使用一种方法,将field1定义为十六进制值(例如,0x40或0x02),并将其放在您想要的地方,这可能是值得的 一个实现可以分配任何足够大的可寻址存储单元来容纳一个位字段。如果仍有足够的空间,结构中紧跟在另一位字段之后的位字段应打包到同一单元的相邻位中。如果空间不足,则将定义是否将不适合的位字段放入下一个单元或与相邻单元

字段的哪一端是最重要的位?

如果您询问myBitField中的哪些位存储在内存中字节的哪些位中,这是C标准明确未定义的。你必须通过实验来学习。如果您正在做一些实际重要的事情,那么使用一种方法,将
field1
定义为十六进制值(例如,
0x40
0x02
),并将其放在您想要的地方,这可能是值得的

一个实现可以分配任何足够大的可寻址存储单元来容纳一个位字段。如果仍有足够的空间,结构中紧跟在另一位字段之后的位字段应打包到同一单元的相邻位中。如果空间不足,则将定义是否将不适合的位字段放入下一个单元或与相邻单元重叠单元内位字段的分配顺序(从高阶到低阶或从低阶到高阶)由实现定义。未指定可寻址存储单元的对齐方式

因此,编译器实现必须记录顺序

然而,很多关于如何实现位字段的信息都是实现定义的或未指定的,因此使用它们以可移植的方式对硬件、有线协议或文件格式的位字段进行建模是不值得尝试的


如果希望“位字段”对程序外部的内容(如上述内容)建模,请使用显式掩码,使用标准的位运算符(
,“&
~
Visual Studio 2008编译器文档指出:

声明为位字段的数据顺序是从低位到高位


中注意:根据标准,MSB没有定义。在您的特定平台上,我怀疑
保留的
包含MSB,但我不是肯定的。@Billy:这看起来像是我的答案。呃……这是一个相当奇怪的问题。您的声明中只有3位字段。其中2位是1位字段,即没有I“哪一端”的问题有了它们,因为那里只有1位。唯一的多位位字段名为
保留
,这表明它根本没有被使用。所以,基本上,你唯一可以问的位字段是
保留
。你是专门问
保留
吗?如果不是,请澄清你的问题。@Ben:如果我是肯定的w.r.t。哪一个变量会得到MSB这是一个答案,但我不是肯定的…这很重要,因为该结构用于定义用于串行通信的数据包。位字段需要在系统的两侧对齐,不幸的是,我只能控制其中的一侧。不幸的是,此端口的功能测试如果不是几个月的话,至少还有几周的时间来编写代码。(要真正测试其中的任何一个代码,还需要编写很多代码,因为我现在所处的位置是,剩下的所有代码或多或少都依赖于其他所有代码。)定义的常量是一个选项,但我更喜欢使用位字段,因为前者在我的代码中需要更多的逻辑。好吧,一个快速的实验应该会告诉你编译器现在在做什么…只需如上所述定义并集,将0分配给
myVar4
,然后将1分配给
field1
,并打印
myVar4
。不过,我会在您之前定义的未使用的位上挂上一个名称,以免编译器将其优化掉。+10如果可以的话。您对这个问题的回答是最好的理由,不要将位字段用于人们认为有用的主要用途。我没有意识到人们试图将其移植使用,我看到的唯一用途是“从我使用编译器X的程序中与硬件对话”,看看无数的“我在编译器X中这么做,在编译器Y中怎么做?”"问题。@CODEABONATOR:例如,我见过用于破解网络协议消息或二进制文件格式的位字段。我还见过一些代码在为其他平台编译时无法工作。这正是位字段的用途。如果未来的C标准定义了这种行为,这将非常有用,但在嵌入式wo中rld位域和并集是程序员和设备制造商在其头文件中必须使用的。请注意,请参阅编译器文档,不要期望它是可移植的。在低级硬件相关代码中使用rld位域和并集,其中需要指定特定位,并且使用掩码会增加代码大小,降低性能和g我没有好处(因为这种类型的代码根据定义是不可移植的)。正如其他人所指出的,相关标准没有规定这一点,编写符合标准的代码是很好的,但这是对所问问题的答案,读者可以决定他们是想将自己的能力用于良好的目的还是令人敬畏的目的