#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.它是怎么来的?有人可以解释一下吗? 我尽力解释它。
答案 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)
内存布局可以看作如下:
前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