#include<stdio.h>
int main()
{
struct s{
int bit_fld:3;
};
s a;
a.bit_fld=0x10;
a.bit_fld =( a.bit_fld | (1<<2));
printf("%x\n",a.bit_fld);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该计划输出fffffffc.
我试图手动计算输出,我无法获得编译器生成的输出.
bit_fld = 00010000 and (1<<2) = 0100oring两个结果00010100都是0x14十六进制的.为什么我对输出的看法是错误的?帮助我理解我错在哪里.
a.bit_fld只有3位大,它无法存储值0x10.行为是实现定义的,但在这种情况下,它可能存储了0.
然后1 << 2是二进制,100如你所说.假设我们在第一步存储了0,结果( a.bit_fld | (1<<2))是int值为4(二进制100).
在带符号的2的补码3位表示中,此位模式表示值-4,因此,如果-4是将值4存储到的值,那就不足为奇了a.bit_fld,尽管这也是实现定义的.
在printf,之前a.bit_fld被提升为intvararg.2的补码32位表示-4 0xfffffffc,这就是你所看到的.
这也是未定义行为的传递int,而不是unsigned int到printf了该%x格式.然而,它似乎起作用并不奇怪:对于一般情况下的varargs,在某些情况下,传递int和读取它是有效的unsigned int.printf不是其中之一,但实施不会让它停止工作.