具有无符号变量的结构位域的 C 代码段行为

C Snippet behavior having struct bitfield of unsigned variables

请帮助我解决与以下代码片段相关的逻辑问题。我得到的输出是 12 8。为什么 *p 是 12? 我知道它的大小是 8,但我对 *p.

显示的值感到不安
int main()    
{    
    struct bitfield
    {
        unsigned a:5;
        unsigned c:5;
        unsigned b:6;
    } bit;

    char *p;

    struct bitfield bit1={1,3,3};

    p=(char*)&bit1;

    p++;

    printf("%d\t%d",*p,sizeof(bit1));

    getchar();

    return 0;
}

首先,

因为声明

struct bitfield
{
    unsigned a:5;
    unsigned c:5;
    unsigned b:6;
}bit;

你的位域 bit 将有 16 位位域,排列如下

00000000 00000000
ccccccbb bbbaaaaa

其次,因为输入的是{1, 3, 3},所以1会赋给a,3会赋给b,另外3会赋给c,就变成这样了

00001100 01100001
ccccccbb bbbaaaaa

第三,因为p只是字符指针,它会最初取两个中的最后一个字节(一个8位),小端格式的地址较小(编辑:尽管 implementation/platform 依赖,请参阅评论和 Abstraction 的另一个答案),因此,p 指向

Additional note from MDSN

The 8086 family of processors stores the low byte of integer values before the high byte

01100001
bbbaaaaa

但是第四,你增加了p!因此,在小端格式中,它现在指向

00001100
ccccccbb

最后,打印 p 指向的值。显然,00001100 只是十进制值 12 的位表示。这就是为什么你得到 12.

这是非常platform/implementation 依赖的代码。假设这些值紧密地包含在 16 位整数中并且字节顺序是小端,那么你的值应该看起来像 (left -> right | lower memory address -> higher memory address)

   1     3     3
  ||     ||    ||
10000 110 00 110000
     ^   ^  ^
     5   8  10

现在 00110000 是 12(符号是从左到右从最低位到最高位,在标准符号中是 00001100)。你的 p 点在前 8 位之后,因为你递增了它。