尝试理解此代码时遇到一些问题:
#include <stdio.h>
typedef union
{
int entero;
struct
{
unsigned short : 7;
unsigned short valor: 1;
} bin;
} conversor;
int main(void)
{
int numero = 8, i;
conversor conver;
conver.entero = numero;
for ( i = 0; i < 8; i++ )
{
printf( "%d", conver.bin.valor );
conver.entero <<= 1;
}
printf( "\n" );
return 0;
}
如果某人愿意解释这段代码如何将整数转换为二进制,那么会以联盟的每个成员为例。
unsigned short : 7;
这是为了什么?
答案 0 :(得分:1)
假设int
为4个字节且short
为2,conversor
将如下所示:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- conversor union
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- int entero
XXXXXXXXXXXXXXXX // <- struct bin
XXXXXXX // <- anonymous field
X // <- valor
XXXXXXXX // <- unused space from bin
union
会将所有成员塞入同一地址,并与其最大成员一样大。位字段将使用按位运算将字段打包为单个位,用户可以明确指定宽度。
您的代码将entero
设置为8,如下所示:
00000000000000000000000000001000
然后printf( "%d", conver.bin.valor );
将输出第8位,即零。
然后conver.entero <<= 1;
会将entero
向左移1位,结果如下:
00000000000000000000000000010000
这会将未命名位字段的值乘以2,valor仍然为0.这样做8次会将entero
移动8位,而i == 3
valor
将会{被“设置”为1(因为你在移位前输出,结果将在下一次迭代中输出。)
在这种情况下,未命名的位字段用作7位填充,因此valor
对应于struct
的第8位。
另请注意,该标准并未强制执行位字段的特定实现,但通常它们遵循常识。