C-如何确定位的存储方式

时间:2018-08-06 01:21:42

标签: c struct unsigned bit-fields

我一直在学习一些有关位字段及其存储方式的知识 下面的结构将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种布局中的哪一种? 预先感谢

3 个答案:

答案 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 xLSBMSB放在y中。