任何人都可以解释输出,如何存储和计算值?
#include<stdio.h>
struct bitfield
{
unsigned f1:1;
unsigned f2:2;
unsigned :3;
unsigned f4:4;
unsigned f5:5;
unsigned f6:6;
unsigned f7:1;
unsigned f8:8;
} bf;
main()
{
bf.f1 = 1;
bf.f2 = 0x3;
bf.f4 = 0xff;
bf.f5 = -4;
bf.f6 = 0377;
printf("%d %d %d %d %d %d", bf.f1, bf.f2, bf.f4, bf.f5, bf.f6, bf.f8);
}
输出:1 3 15 28 63 0
答案 0 :(得分:4)
非常短暂的破坏。
首先,bf
是未初始化的全局变量。这意味着它将最终进入.bss
段,通常在启动时初始化为零(尽管您可以将-fno-zero-initialized-in-bss
传递给GCC以阻止此操作,不确定MSVC,当然这取决于你的crt0
)。这解释了f8
的价值,因为您尚未写入。{/ p>
f1
是1.你指定它1.那是显而易见的。与f2
相同(因为hex 3是dec 3)。
f4
是因为f4的字段只有4位宽。 0xFF
是一个8位模式,它是全1,然后被截断为4位,因此是15(可以用4位表示的最高值)。
f5
是由签名/未签名转换引起的。 -4位的5位二的恭维表示是11100.如果将该值解释为无符号(或者更确切地说,只是简单的二进制 - >十进制转换),则得到28。
f6
为63。任何以零开头的C字面数都被视为八进制。八进制377是十进制255(在8位中为11111111),然后被截断为6位,留下111111
。这是63。
答案 1 :(得分:2)
值存储在您指定的字段中。但是,由于在某些情况下,例如bf.f4 = 0xff;
,该值不适合,它将丢失高位,因此它打印15(0x0F)。类似地,对于存储在f5
-4 = 0xFFFFFFFC
中的-4作为32位整数,但当作为无符号5位整数存储时,它变为0x1C或28.同样的原则适用于{{1} }。
在f6
和f2
之间使用未命名的成员也有3位“差距”。
在内部,编译器将通过使用AND,SHIFT和OR操作来完成此操作。
请注意,我们无法知道f4
是否是存储字段的整个值的最高位或最低位。这是编译器实现将决定的内容 - 只要它完成了每次都是一样的。
答案 2 :(得分:1)
unsigned fx:n; // Only use the least significant n bits.
// Binary Decimal
bf.f1 = 1; // 1 == [0000 0001]:1 == 1 == 1
bf.f2 = 0x3; // 0x3 == [0000 0011]:2 == 11 == 3
bf.f4 = 0xff; // 0xff == [1111 1111]:4 == 1111 == 15
bf.f5 = -4; // -4 == [0xfffffffc]:5 == 11100 == 28
bf.f6 = 0377; // 0377 == [1111 1111]:6 == 111111 == 63
答案 3 :(得分:0)
unsigned f1:1; // 1 bit is allocated.
bf.f1=1; // you are storing 1 works fine.
unsigned f2:2; // 2 bit is allocated.
bf.f2=0x3; // 3 == '11' in binary so 2 bits are enough so when you print 3 is printed.
unsigned :3;
unsigned f4:4; // 4 bit is allocated.
bf.f4=0xff; // ff is represented as 1111 1111 in binary,
// but only 4 bits are allocated so only f which is 1111
// in binary gets stored in this. when you print using %d, 15 is getting printed.
unsigned f5:5; // 5 bits are allocated
bf.f5=-4; // -4 in binary for 5 bits is 11100 but you are printing it as %d so it will print 28. and so on...
希望这会有所帮助。