联合和位域——它们是如何工作的?
Unions and bit fields — how do they work?
我在尝试理解这段代码时遇到了一些问题:
#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;
这是做什么用的?
假设 int
是 4 个字节,short
是 2 个字节,conversor
看起来像这样:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- conversor union
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- int entero
XXXXXXXXXXXXXXXX // <- struct bin
XXXXXXX // <- anonymous field
X // <- valor
XXXXXXXX // <- unused space from bin
A union
会将其所有成员塞入同一地址,并与其最大成员一样大。位字段将使用按位运算将字段打包成单独的位,用户可以明确指定位的宽度。
您的代码将 entero
设置为 8,如下所示:
00000000000000000000000000001000
那么printf( "%d", conver.bin.valor );
会输出第8位,也就是0。
然后 conver.entero <<= 1;
将 entero
向左移动 1 位,结果是:
00000000000000000000000000010000
这会将未命名位字段的值乘以 2,valor 仍将为 0。这样做 8 次会将 entero
移位 8 位,并且在 i == 3
valor
会"set"到1(因为你在shift之前输出,所以下一次迭代会输出结果)。
在这种情况下,未命名的位字段用作 7 位填充,因此 valor
对应于 struct
.
的第 8 位
另请注意,该标准并未强制执行位字段的特定实现,但通常它们遵循常识。
我在尝试理解这段代码时遇到了一些问题:
#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;
这是做什么用的?
假设 int
是 4 个字节,short
是 2 个字节,conversor
看起来像这样:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- conversor union
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // <- int entero
XXXXXXXXXXXXXXXX // <- struct bin
XXXXXXX // <- anonymous field
X // <- valor
XXXXXXXX // <- unused space from bin
A union
会将其所有成员塞入同一地址,并与其最大成员一样大。位字段将使用按位运算将字段打包成单独的位,用户可以明确指定位的宽度。
您的代码将 entero
设置为 8,如下所示:
00000000000000000000000000001000
那么printf( "%d", conver.bin.valor );
会输出第8位,也就是0。
然后 conver.entero <<= 1;
将 entero
向左移动 1 位,结果是:
00000000000000000000000000010000
这会将未命名位字段的值乘以 2,valor 仍将为 0。这样做 8 次会将 entero
移位 8 位,并且在 i == 3
valor
会"set"到1(因为你在shift之前输出,所以下一次迭代会输出结果)。
在这种情况下,未命名的位字段用作 7 位填充,因此 valor
对应于 struct
.
另请注意,该标准并未强制执行位字段的特定实现,但通常它们遵循常识。