0

让我们考虑以下代码

#include <stdio.h>
#include <iostream>
using namespace std;
typedef struct bf_{
    unsigned x:4;
    unsigned y:4;
    unsigned z:4;
    unsigned  w:4;
    }bf;
int main(){
    unsigned short i=8;
    unsigned short j=9;
    bf* bitfields=(bf *)&i;
    bf*bit=(bf*)&j;
    bitfields->w=12;
    printf("%d\n",bitfields->x);
    printf("%d\n",bit->y);
    printf("%d\n",bitfields->w);



     return 0;
}

这个片段

unsigned short j=9;
bf*bit=(bf*)&j;
printf("%d\n",bit->y);

我在猜测后添加了一些有趣的代码特征,例如在这个地方之后

bf* bitfields=(bf *)&i;

当我们写printf("%d\n",bitfields->x);which prints 8 我明白使用指针和引用 i 的值将被授予 x 所以它打印 8 例如当我们写它时bitfiled->y它写 0 所以我决定引入第二个元素变量 j 创建 bf 结构的新实例和引用 j 之后的语句 bit->y 应该写 9 因为据我了解它是订单定义但它给了我 0 为什么?请解释一下这段代码是如何工作的?我不会说英语,所以请原谅我的英语不好

4

2 回答 2

3

首先,此代码中没有使用任何引用。该&字符在用作一元运算符(而不是作为类型名称的一部分)时,如在此上下文中,表示“地址”。&i“地址”也是如此i而不是“引用i”。

我不确定你从哪里得到使用值 9 作为你的bf结构应该导致y获取 value的想法9。当你写这个:

bf* bitfields=(bf *)&i;

发生的情况是您告诉编译器“将内存位置的值&i视为bf结构”。该bf结构被定义为,从最低有效(最右边)位开始,前四位是x值,后四位是y值,第三四位是z值,等等。

因此,由于该位置的&i值为8,并且 16 位二进制中的 8 是

0000 0000 0000 1000 

的领域bitfields将是:

0000 0000 0000 1000 
  w    z    y    x

所以x(一个 4 位无符号整数)的值为 8,而yzw的值为 0。

在你写的情况下

bf*bit=(bf*)&j;

你正在做与上面相同的事情,除了现在值是 9,所以分配是:

0000 0000 0000 1001 
  w    z    y    x

值 9 也是如此x,其他值仍为 0。

如果要将值 9 分配给y而不是x,则分配需要如下所示:

0000 0000 1001 0000 
  w    z    y    x

所以你必须使用的值是 16 位二进制表示的值

0000 0000 1001 0000 

这是 144。所以如果你让j = 144而不是j = 9,你会发现它bit->y是 9,并且所有其他字段bit都是 0。

于 2010-09-27T15:14:42.917 回答
0

我认为这是因为编译结构或类时发生的打包。请参阅以下链接:

http://msdn.microsoft.com/en-us/library/83ythb65.aspx#vclrfhowalignworkswithdatapacking
http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx

默认情况下,编译时结构大小与其成员的总大小不同。

于 2010-09-27T15:36:56.307 回答