该程序的输出说明(结构中的位域)

时间:2013-06-16 05:01:15

标签: c coding-style structure

#include <stdio.h>

int main()
{
    struct bitfield 
    {
         unsigned a:5;
         unsigned c:5;
         unsigned b:6;
    } bit;

    char *ptr;
    struct bitfield bit1={1,3,3};

    ptr=&bit1;
    ptr++;

    printf("%d",*ptr);
    return 0;
}

这个问题的输出是12.它是怎么来的?有人可以解释一下吗? 我尽力解释它。

4 个答案:

答案 0 :(得分:14)

对这个问题的解释相当简单:

Binary value of 1 is 00001 (as "a" have 5 bitfield)
Binary value of 3 is 00011 (as "c" have 5 bitfield)
Binary value of 3 is 000011 (as "b" have 6 bitfield)

内存布局可以看作如下: enter image description here

前5个位被a占用并且值为00001.然后5位被b占用,其值为00011,最后6位被c占用,值为000011。

因此,在开始时,指针ptr位于内存位置1000,现在当你执行ptr++时。由于sizeof(char)为1,ptr将移动1个内存位置。因此ptr移动到内存位置1001。

因此*ptr将为您提供存储在内存位置1001的值, 因此,答案将是12

答案 1 :(得分:2)

如何使用5位表示1?它将 00001 ,3将 00011 (请注意,b有6个位域,因此它还有额外的零: 000011 )。

现在我们假设bit1的地址是1000. ptr++会是什么?它将是1001(因为sizeof ptr是1)。

*ptr的含义是什么?它表示位置1001的内容,它将是00001100.

二进制00001100是小数 12

答案 2 :(得分:2)

初始化后,位域具有以下值:

000011 00011 00001
^^^^^^ ^^^^^ ^^^^^
b = 3  c = 3 a = 1

假设char为8位宽,您可以将16位分成两个8位部分:

00001100 01100011
^^^^^^^^ ^^^^^^^^
 ptr + 1   ptr

所以你将在ptr + 1打印八位字节,即12。

然而,我很确定这会调用未定义的行为,,因为不应该使用位域的地址(更不用说通过甚至是不兼容的类型...)

答案 3 :(得分:2)

用于演示a,b和c存储位置的程序。请注意,由于字节序,它会有点混乱。

#include<stdio.h>
#include<string.h>

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

void print_bitfield(unsigned a, unsigned c, unsigned b)
{
    struct bitfield bf;
    memset(&bf, 0, sizeof(bf));
    bf.a = a;
    bf.b = b;
    bf.c = c;

    unsigned char* ptr = (unsigned char*)&bf;
    unsigned i;

    printf("%2x %2x %2x: ", a, c, b);
    for (i = 0; i < sizeof(bf); i++)
    {
        printf("%02x ", ptr[i]);
    }
    printf("\n");
}

int main()
{
    printf("sizeof bitfield: %u\n",sizeof(struct bitfield));

    printf(" a  c  b:  0  1  2  3\n");
    print_bitfield(0,  0, 0);
    print_bitfield(1,  0, 0);
    print_bitfield(31, 0, 0);
    print_bitfield(0,  1, 0);
    print_bitfield(0, 31, 0);
    print_bitfield(0,  0, 1);
    print_bitfield(0,  0, 63);
    print_bitfield(1, 3, 3);
    return 0;
}

输出:

sizeof bitfield: 4
 a  c  b:  0  1  2  3
 0  0  0: 00 00 00 00 
 1  0  0: 01 00 00 00 
1f  0  0: 1f 00 00 00 
 0  1  0: 20 00 00 00 
 0 1f  0: e0 03 00 00 
 0  0  1: 00 04 00 00 
 0  0 3f: 00 fc 00 00 
 1  3  3: 61 0c 00 00