從網上看到這樣一段c代碼,讓我發覺個人C基本功仍是不行啊~~ide
- typedef struct xp {
- int a:2;
- int b:2;
- unsigned int c:1;
- } xp;
不知道你們對int聲明中的這個":"熟悉嗎?不過,我剛看到的時候有點懵。在網上查了些資料,才明白這是一種將int按位分配的方法。spa
好比:int a:2;表示a爲佔2位的整數。內存
一般的int爲4字節,即佔用32位的整數。string
同時 按位分配的int,也分有符號和無符號兩種,如:it
- typedef xp
- {
- int a:2;
- unsigned int b:2;
- }MyXp;
- MyXp x;
- x.a = 3;
- x.b = 3;
這樣,輸出的x.a爲-1,x.b爲3。編譯
同時,你們看到,這種分配方法是定義在struct中的。若是你在代碼中直接定義:int a:2;編譯時會致使錯誤,沒法識別「:」。class
這是由於int是內建類型,它不能被改變內存分配的方式。因此單獨的int,不能直接被聲明爲只佔2位。變量
而在struct中,對整個struct的內存分配,仍是遵循c的內存分配方式,但在其中每個內存位的表示含義,則能夠由咱們本身說明。以下:方法
- printf("%d\n", sizeof(x));
- printf("%d\n",sizeof(x.a));
第一句能返回4,表示MyXp是佔用4個字節的,其實其中的多個int,對系統來講只是將一個int截成了不一樣的段來使用,整個內存分配仍是按照一個int來。固然,若是總位數超過了32位,那struct大小會以4字節爲單位遞增,即struct的大小爲4字節、8字節、12字節等。word
而同時,第二句printf編譯錯誤,是由於系統識別不出x.a的類型,由於他不是普通的int類型,系統沒法識別x.a佔用了2位。
從內存上看,a和b佔用了x的32位中的低4位,高位沒有分配的會以0值填充。
有興趣的能夠看一下運行時的內存分配。struct中的a、b是公用一個int的內存段,若是再添加新的變量,他們也是使用同一個int內存段,直到一個int段不夠,則直接再開一個int段供使用。同時,若是反編譯這段代碼,也能發現,對a、b的賦值和訪問和通常的int不一樣,是經過位操做來進行的。
注意,共享內存段的只能是在struct中連續聲明的按位分配的int變量,以下聲明:
- typedef struct xp {
- int a:3;
- int b:2;
- int k;
- unsigned int c:2;
- } xp;
則xp會佔用3個int的內存段,由於a、b共享一個int的4字節,k本身單獨佔用一個int,c則須要開一個新的int內存段使用。而若是將k和c的聲明互換,則xp只須要佔用2個int的內存段。