2013-04-30 113 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的維基百科。