[英]value of members of unions with bit-fields
我正在尝试学习如何为包含位字段的联合分配内存。
我查看了与此类似的帖子和问题,并且了解到填充在大多数情况下都取决于成员在结构中声明的顺序。
1。
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
输出:-1
2。
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
输出3
有人可以解释一下输出结果吗? 仅仅是这种情况下的标准输出吗? 我在ubuntu中使用内置的gcc编译器
你的编译器分配在工会位字段位的方式发生的低位重叠j
用的比特i
。 因此,当j
设置为15时, i
的两位分别设置为1。
当i
是用int i:2
声明的两位带符号整数时,编译器会将其解释为两位二进制的补码。 通过这种解释,比特11代表-1。
当i
是由unsigned int i:2
声明的两位无符号整数时,它是纯二进制,没有符号位。 通过这种解释,位11代表3。
下面的程序显示,至少在您的C实现中,将有符号的两位整数设置为-1或将无符号的两位整数设置为3会在联合中产生相同的位模式。
#include <stdio.h>
int main(void)
{
union Example
{
unsigned u;
int i : 2;
int j : 9;
unsigned int k : 2;
} ex;
ex.u = 0;
ex.i = -1;
printf("ex.i = -1: %#x.\n", ex.u);
ex.u = 0;
ex.j = 15;
printf("ex.j = 15: %#x.\n", ex.u);
ex.u = 0;
ex.k = 3;
printf("ex.k = 3: %#x.\n", ex.u);
}
输出:
ex.i = -1: 0x3. ex.j = 15: 0xf. ex.k = 3: 0x3.
请注意,编译器还可以从高到低而不是从低到高分配位,在这种情况下, j
的高位将与i
重叠,而不是低位。 同样,编译器为9位j
使用的存储单元大小可能与为2位i
使用的存储单元大小不同,在这种情况下,它们的位可能根本不重叠。 (例如,它可能对i
使用单个8位字节,但对j
使用32位字。这8位字节会与32位字的某些部分重叠,但不一定与j
所用的部分重叠。 )
例1
#include <stdio.h>
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
printf("\nSize of Union : %lu\n" , sizeof(ex));
return 0;
}
输出:
-1
Size of Union : 4
观察结果:
从这个输出中,我们可以推断出,即使我们使用9位(最大值),编译器也会分配4字节(由于填充)。 声明union Example ex;
为联合示例对象ex分配4字节的内存。 语句ex.j=15;
将0x0000000F分配给该4字节的内存。 因此,对于j,它为9位分配0-0-0-0-0-1-1-1-1。 语句printf("%d",ex.i);
尝试打印ex.i(2位)。 从前面的语句中我们得到1-1。
有趣的部分到了,例如ex.i的类型为int。 因此,第一位用于分配带符号的表示,大多数cpu以2的补码形式表示带符号的表示。 因此,如果我们反转1-1的2的补数,我们将获得值1。因此,我们得到的输出为-1。
例2
#include <stdio.h>
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
return 0;
}
输出:
3
观察结果:
声明union Example ex;
为联合示例对象ex分配4字节的内存。 语句ex.j=15;
将0x0000000F分配给该4字节的内存。 因此,对于j,它为9位分配0-0-0-0-0-1-1-1-1。 语句printf("%d",ex.i);
尝试打印ex.i(2位)。 从前面的语句中我们得到1-1。
与上述示例相同,但此处ex.i的类型为unsigned int。 因此,这里没有符号位用于表示。 因此,存储在2位位置中的是确切值。 因此输出为3。
希望我清除您的疑虑。 请在互联网上检查2和1的补码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.