本文為摘抄并修改,原文:http://www.cnblogs.com/dolphin0520/archive/2011/10/03/2198493.html
聯(lián)合體例子:
union U
{
char s[9];
int n;
double d;
};
s占9字節(jié),n占4字節(jié),d占8字節(jié),因此sizeof(U)至少9字節(jié)。然而用運算符sizeof測試其大小為16。這是因為字節(jié)對齊,9既不能被4整除,也不能被8整除。因此補充字節(jié)到16,這樣就符合所有成員的自身對齊了。
從這里可以看出聯(lián)合體所占的空間不僅取決于最寬成員,還跟所有成員有關系。即其大小必須滿足兩個條件:
- 1)大小足夠容納最寬的成員;
- 2)大小能被其包含的所有基本數(shù)據(jù)類型的大小所整除。
#include <stdlib.h>
#include <stdio.h>
union U1
{
char s[9];
int n;
double d;
};
union U2
{
char s[5];
int n;
double d;
};
int main(int argc, char *argv[])
{
union U1 u1;
union U2 u2;
printf("%ld\n",sizeof(u1));
printf("%ld\n",sizeof(u2));
printf("0x%p\n",&u1);
printf("0x%p\n",&u1.s);
printf("0x%p\n",&u1.n);
printf("0x%p\n",&u1.d);
u1.n=1;
printf("%d\n",u1.s[0]);
printf("%lf\n",u1.d);
u1.n=97;
printf("%c\n",u1.s[0]);
return 0;
}
cloud@cloud:/web/code/c$ ./union
16
8
0x0x7ffffdc698a0
0x0x7ffffdc698a0
0x0x7ffffdc698a0
0x0x7ffffdc698a0
1
0.000000
a
對于sizeof(u1)=16。因為u1中s占9字節(jié),n占4字節(jié),d占8字節(jié),因此至少需要9字節(jié)。其包含的基本數(shù)據(jù)類型為char,int,double分別占1,4,8字節(jié),為了使u1所占空間的大小能被1,4,8整除,則需填充字節(jié)以到16,因此sizeof(u1)=16.
對于sizeof(u2)=8。因為u2中s占5字節(jié),n占4字節(jié),d占8字節(jié),因此至少需要8字節(jié)。其包含的基本數(shù)據(jù)類型為char,int,double分別占1,4,8字節(jié),為了使u2所占空間的大小能被1,4,8整除,不需填充字節(jié),因為8本身就能滿足要求。因此sizeof(u2)=8。
從打印出的每個成員的基地址可以看出,聯(lián)合體中每個成員的基地址都相同,等于聯(lián)合體變量的首地址。
對u1.n=1,將u1的n賦值為1后,則該段內存的前4個字節(jié)存儲的數(shù)據(jù)為00000001 00000000 00000000 00000000
因此取s[0]的數(shù)據(jù)表示取第一個單元的數(shù)據(jù),其整型值為1,所以打印出的結果為1.
至于打印出的d為0.000000愿意如下。由于已知該段內存前4字節(jié)的單元存儲的數(shù)據(jù)為00000001 00000000 00000000 00000000,從上面打印結果48,204,64,0可以知道后面4個字節(jié)單元中的數(shù)據(jù)為00110000 11001100 01000000 00000000,因此其表示的二進 制浮點數(shù)為
00000000 01000000 11001100 00110000 00000000 00000000 00000000 00000001
對于double型數(shù)據(jù),第63位0為符號位,62-52 00000000100為階碼,0000 11001100 00110000 00000000 00000000 00000000 00000001為尾數(shù),根據(jù)其值知道尾數(shù)值約為0,而階碼為4-1023=-1019,因此其表示的浮點數(shù)為1.0*2^(-1019)=0.00000000000......,因此輸出結果為0.000000。
至于
u1.n=97;
printf("%c\n",u1.s[0]);
return 0;
我這里寫入的是4字節(jié)的int型數(shù)據(jù)97;
卻以字符串格式來打印,打印出ascii對應97的字母a。
為什么要內存對齊?
http://www.lxweimin.com/p/0355f83ff557