位字段操作

时间:2013-01-13 20:35:44

标签: c++ bit-fields

在以下代码中

#include <iostream>

using namespace std;
struct field
{
   unsigned first : 5;
   unsigned second : 9;
};
int main()
{
   union
   {
      field word;
      int i;
   };
   i = 0;
   cout<<"First is : "<<word.first<<" Second is : "<<word.second<<" I is "<<i<<"\n";
   word.first = 2;
   cout<<"First is : "<<word.first<<" Second is : "<<word.second<<" I is "<<i<<"\n";
   return 0;
}

当我初始化word.first = 2时,正如预期的那样,它会更新该字的5位,并提供所需的输出。这是'i'的输出有点令人困惑。使用word.first = 2,我将输出设为2,当我执行word.second = 2时,i的输出为64.因为,它们共享相同的内存块,在后一种情况下,输出(对于i)不应该是2?

2 个答案:

答案 0 :(得分:7)

此特定结果是特定于平台的;你应该阅读endianness

但要回答你的问题,不,word.firstword.second不共享记忆;他们占据了不同的位。显然,您平台上的基础表示是:

bit   15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |     |         second           |    first     |
     +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     |<------------------- i ----------------------->|

因此设置word.second = 2会设置i的第6位,而2 6 = 64。

答案 1 :(得分:1)

虽然这取决于您的平台和您的特定编译器,但这是您的情况:

union将int和struct叠加到同一个内存中。现在让我们假设你的int的大小为32位。同样,这取决于多种因素。你的内存布局看起来像这样:

IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
                  SSSSSSSSSFFFFF

代表整数, S 代表第二个字段, F 代表结构的第一个字段。请注意,我已经代表左侧最重要的位。

将整数初始化为零时,所有位都设置为零,因此第一个和第二个也为零。 将word.first设置为2时,内存布局将变为:

00000000000000000000000000000010
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
                  SSSSSSSSSFFFFF

对于整数,哪个值为2。但是,通过将word.second的值设置为2,内存布局变为:

00000000000000000000000001000000
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
                  SSSSSSSSSFFFFF

这为整数提供了64的值。