2013-04-30 90 views
1

我正在使用C中的位字段,并不明白与他们发生了什么。我创建了这个代码,但我不明白为什么不同的东西会像平常一样出现。位场混淆?

struct tB 
{ 
unsigned b1:3; 
signed b2:6; 
unsigned b3:11; 
signed b4:1; 
} b; 


int main(void) 
{ 
struct tB *p; 

printf("%d\n", sizeof(*p)); 
} 

为什么当我打印出来*p做我得到4*p

让我们说我试图得到sizeof(b),我会怎么想出来的?

回答

3

sizeof(b)会给你在struct tB类型的变量,在这种情况下将是4字节的大小(由于padding它不会是3,因为它预期是)

sizeof(*p)将再次给你struct tB类型的变量的字节数。您应该struct tB type.Eg的变量的地址初始化p

struct tB *p=&b; 

但是你应该知道,在这种情况下,如果你使用sizeof(p)吨如果它会给出指针p的大小,而不是p指向的变量。试试你的程序的这种变化:

#include<stdio.h> 

struct tB 
{ 
unsigned b1:3; 
signed b2:6; 
unsigned b3:11; 
signed b4:1; 
unsigned b5:13; 
} b; 


int main(void) 
{ 
struct tB *p; 

printf("%d\n%d",sizeof(*p),sizeof(p)); 
} 

这里是另一个变化是轮struct tB 24位(3个字节),你期望的那样,通过处理使用#pragma pack()指令填充,这是依赖于编译器(大小我在Windows上使用CodeBlocks)。

#include<stdio.h> 
#pragma pack(1) 
struct tB 
{ 
unsigned b1:3; 
signed b2:6; 
unsigned b3:11; 
signed b4:1; 

} b; 


int main(void) 
{ 
struct tB *p; 

printf("%d\n%d",sizeof(*p),sizeof(p)); 
} 
+0

谢谢!即时通讯不知道第二个声明是说什么? – RightLeftRight12 2013-04-30 06:03:05

+0

@ user2127663让我编辑并清除。 – 2013-04-30 06:03:35

+0

好的,如果我只是要求sizeof(p),它会给我4,因为它的指针是正确的? – RightLeftRight12 2013-04-30 06:05:20

1

你有21位,四舍五入到最接近的int,你有32位(即4字节)。

+0

为什么我会轮到32? 24不会成为下一个? – RightLeftRight12 2013-04-30 05:36:43

+0

@ user2127663没有24位整数类型。您可以选择的字符是char(8位),short(16位),int(32位),long(32或64位)和long long(64位)。对于位域,除非另有说明,否则它将始终使用'int',因此始终填充到最近的32位边界。 – 2013-04-30 05:38:13

+0

哦,好吧,完美,让人感觉很棒!所以如果我在找b,它也会是一样的吗? – RightLeftRight12 2013-04-30 05:39:34

0

这是关于处理器的一句话。访问内存的处理器无法访问它,比如1或2个字节。它通过单词获取它。通常,编译器会对结构进行适当的对齐以符合字对齐。通常,通过处理器寄存器的大小,这种对齐方式与处理器架构相同。所以,在你的情况下,你有21位结构与一个字对齐。如果你将你的结构调整为33位长,你将有2个字对齐,在你的情况下,程序将打印8个。

这里的文章涉及到这个Data structure alignment的维基百科。