4
#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

4 回答 4

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)

内存布局可以这样可视化: 在此处输入图像描述

前 5 位被a值 00001 占用。然后 5 位被b值 00011 占用,最后 6 位被c值 000011 占用。

所以,在起始指针ptr是在内存位置 1000,现在当你做了ptr++. 由于sizeof(char)为 1,ptr将移动 1 个内存位置。所以ptr移动到内存位置 1001。

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

于 2013-06-16T05:23:14.367 回答
2

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

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

是什么*ptr意思?这意味着位置 1001 的内容将是 00001100。

二进制 00001100 是十进制12

于 2013-06-16T05:23:03.340 回答
2

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

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

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

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

因此,您将在 ptr + 1 处打印八位字节,即 12。

但是,我很确定这会调用未定义的行为,因为不应使用位域的地址(更不用说通过甚至是不兼容类型的指针来别名了......)

于 2013-06-16T05:25:40.117 回答
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 
于 2013-06-16T06:03:38.663 回答