让我们考虑以下代码
#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);
打印8时我明白使用指针和引用i的值将被授予x,所以它打印8例如当我们写bitfiled->y
时它写0所以我决定引入第二个元素变量j创建bf structer的新实例并在其后引用j
声明bit-&gt; y应该写9,因为据我所知它是订单定义,但它给我0为什么?请解释一下这个代码是如何工作的?我不是说英语的人,所以请抱歉我的英文不好
答案 0 :(得分:3)
首先,此代码中没有使用引用。 &
字符用作一元运算符(而不是类型名称的一部分),如在此上下文中,表示“地址”。因此&i
是“i
”的地址,不是“对i
的引用”。
我不确定您认为使用值9作为bf
结构会导致y
获取值9
的想法。当你这样写:
bf* bitfields=(bf *)&i;
您要告诉编译器“将内存位置&i
的值视为bf
结构”,会发生什么。定义bf
结构,以便从最低有效(最右边)位开始,前四位是x
值,后四位是y
值,第三个四位是z
值,等等。
因为位置&i
的值为8
,而16位二进制中的值为
0000 0000 0000 1000
bitfields
的字段将是:
0000 0000 0000 1000
w z y x
因此x
(一个4位无符号整数)的值为8,而y
,z
和w
的值为0。
在你写的情况下
bf*bit=(bf*)&j;
你正在做与上面相同的事情,除了现在值为9,所以分配是:
0000 0000 0000 1001
w z y x
因此x
的值为9,其他值仍为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
答案 1 :(得分:0)
我认为这是因为编译结构或类时发生的打包。 请参阅以下链接:
http://msdn.microsoft.com/en-us/library/83ythb65.aspx#vclrfhowalignworkswithdatapacking。
http://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx
默认情况下,编译时结构的大小不与其成员的总大小相同。