我一直在学习一些有关位字段及其存储方式的知识 下面的结构将32位无符号int分为3个分量:x,y和z。
struct bit_num {
unsigned int x : 4,
y : 8,
z :20;
}
因此,编译器确定如何将字段放置在无符号int内,这是2之一:
[x(4位)] [y(8位)] [z(20位)]
或
[z(20位)] [y(8位)] [x(4位)]
我的问题是,如何确定使用上面的结构在这里使用的是2种布局中的哪一种? 预先感谢
答案 0 :(得分:0)
使用4velements无符号char数组将其包装为并集。在程序中,将位域之一设置为已知值。打印阵列,您将知道。
没有其他需要
答案 1 :(得分:0)
您可以使用union
分析位域的布局。例如:
#include <stdio.h>
struct bit_num {
unsigned int x : 4,
y : 8,
z :20;
};
union bit_layout
{
unsigned int w;
struct bit_num b;
unsigned char c[sizeof(unsigned int)];
};
int main(void)
{
union bit_layout bl = { .b = { .x = 0xF, .y = 0xA5, .z = 0xC800C } };
printf(".x = 0x%X, .y = 0x%.2X, .z = 0x%.5X, .w = 0x%.8X\n",
bl.b.x, bl.b.y, bl.b.z, bl.w);
printf("c[0] = 0x%.2X, c[1] = 0x%.2X c[2] = 0x%.2X, c[3] = 0x%.2X\n",
bl.c[0], bl.c[1], bl.c[2], bl.c[3]);
return 0;
}
在运行带有GCC 8.2.0的macOS 10.13.6的Mac上,我得到了输出:
.x = 0xF, .y = 0xA5, .z = 0xC800C, .w = 0xC800CA5F
c[0] = 0x5F, c[1] = 0xCA c[2] = 0x00, c[3] = 0xC8
因此,位字段的.x
成员存储在最低有效字节中。 .y
成员存储在接下来的两个字节中;并且.z
成员存储在5个最高有效字节中。但是,字节布局显示索引为0的数组的字节保留.x
,而.y
值的低半部分则保留;索引为1的字节保留.y
值的较高半部分,而.z
值的最低有效的半字节,而数组的其余两个字节包含{{1} }值。
答案 2 :(得分:0)
这是一个示例程序。
sed
编译它并使用 LGA off.cat sub.cat Jan1995 Feb1995
1 Albury Homicide Murder * 0 0
2 Albury Homicide Attempted murder 0 0
3 Albury Homicide Murder accessory, conspiracy 0 0
4 Albury Homicide Manslaughter * 0 0
5 Albury Assault Domestic violence related assault 7 7
6 Albury Assault Non-domestic violence related assault 29 20
7 Albury Assault Assault Police 12 3
8 Albury Sexual offences Sexual assault 4 3
转储struct bit_num {
unsigned int x : 4,
y : 8,
z :20;
};
struct bit_num bm = {0x1, 0x23, 0x45678};
void main()
{
}
部分。
objdump -d -j .data a.out
从低地址到高地址的字节为.data
。因为二进制数的最高有效位(也称为MSB)是最左边的位,所以我们将这四个字节从高地址写入低地址:
000000000060102c <bm>:
60102c: 31 82 67 45
然后将它们转换为二进制数:
31 82 67 45
此二进制数可分为以下几类:
45 67 82 31
然后您可以知道01000101 01100111 10000010 00110001
,MSB -------------------------- LSB
01000101011001111000 00100011 0001
(20bits) (8bits) (4bits)
z=0x45678 y=0x23 x=0x1
和x
从LSB到MSB放在y
中。