sizeof()功能:計(jì)算數(shù)據(jù)空間的字節(jié)數(shù)
1.與strlen()比較
??????strlen()計(jì)算字符數(shù)組的字符數(shù),以"\0"為結(jié)束判斷。
??????而sizeof計(jì)算數(shù)據(jù)(包括數(shù)組、變量、類型、結(jié)構(gòu)體等)所占內(nèi)存空間,用字節(jié)數(shù)表示
2.指針與靜態(tài)數(shù)組的sizeof操作
??????指針均可看為變量類型的一種。所有指針變量的sizeof 操作結(jié)果均為4。
??????注意:int *p; sizeof(p)=4;
???????????????????但sizeof(*p)相當(dāng)于sizeof(int);??????
??????對(duì)于靜態(tài)數(shù)組,sizeof可直接計(jì)算數(shù)組大小;
??????例:int a[10];char b[]="hello";
??????????????sizeof(a)等于10;
????????????? sizeof(b)等于7;
??????注意:數(shù)組做型參時(shí),數(shù)組名稱當(dāng)作指針使用!!
???????????????void? fun(char p[])
???????????????{sizeof(p)等于4}
????
? 經(jīng)典問(wèn)題:?

??????double* (*a)[3][6];?

??????cout<<sizeof(a)<<endl; // 4?
??????cout<<sizeof(*a)<<endl; // 72?
??????cout<<sizeof(**a)<<endl; // 24?
??????cout<<sizeof(***a)<<endl; // 4?
??????cout<<sizeof(****a)<<endl; // 8?

??????a
是一個(gè)很奇怪的定義,他表示一個(gè)指向double*[3][6]類型數(shù)組的指針。既然是指針,所以sizeof(a)就是4?

??????
既然a是執(zhí)行double*[3][6]類型的指針,*a就表示一個(gè)double*[3][6]的多維數(shù)組類型,因此sizeof(*a)
???? =3*6*sizeof(double*)=72
。同樣的,**a表示一個(gè)double*[6]類型的數(shù)組,所以sizeof(**a)=6*sizeof? (double*)=24***a就表示其中的一個(gè)元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一個(gè)double了,所以sizeof(****a)=sizeof(double)=8
?

3.格式的寫(xiě)法
???sizeof操作符,對(duì)變量或?qū)ο罂梢圆患永ㄌ?hào),但若是類型,須加括號(hào)
4
.使用sizeof時(shí)string的注意事項(xiàng)
???string s="hello";
???sizeof(s)等于string類的大小,sizeof(s.c_str())得到的是與字符串長(zhǎng)度。
5.union 與struct的空間計(jì)算
???總體上遵循兩個(gè)原則:
???(1)整體空間是
占用空間最大的成員(的類型)所占字節(jié)數(shù)的整倍數(shù)
?? (2)數(shù)據(jù)對(duì)齊原則----內(nèi)存按結(jié)構(gòu)成員的 先后順序排列,當(dāng)排到該成員變量時(shí),其前面已擺放的空間大小必須是該成員類型大小的整倍數(shù),如果不夠則補(bǔ)齊,以此向后類推。。。。。
?? 注意:數(shù)組按照單個(gè)變量一個(gè)一個(gè)的擺放,而不是看成整體。如果成員中有自定義的類、結(jié)構(gòu)體,也要注意數(shù)組問(wèn)題。
例:[引用其他帖子的內(nèi)容]
因?yàn)閷?duì)齊問(wèn)題使結(jié)構(gòu)體的sizeof變得比較復(fù)雜,看下面的例子:(默認(rèn)對(duì)齊方式下)

struct s1
{
char a;
double b;
int c;
char d;
};

struct s2
{
char a;
char b;
int c;
double d;
};

cout<<sizeof(s1)<<endl; // 24
cout<<sizeof(s2)<<endl; // 16

?
同樣是兩個(gè)char類型,一個(gè)int類型,一個(gè)double類型,但是因?yàn)閷?duì)界問(wèn)題,導(dǎo)致他們的大小不同。計(jì)算結(jié)構(gòu)體大小可以采用元素?cái)[放法,我舉例子說(shuō)明一下:首先,CPU判斷結(jié)構(gòu)體的對(duì)界,根據(jù)上一節(jié)的結(jié)論,s1s2的對(duì)界都取最大的元素類型,也就是double類型的對(duì)界8。然后開(kāi)始擺放每個(gè)元素。
?
對(duì)于s1,首先把a放到8的對(duì)界,假定是0,此時(shí)下一個(gè)空閑的地址是1,但是下一個(gè)元素ddouble類型,要放到8的對(duì)界上,離1最接近的地址是8了,所以d被放在了8,此時(shí)下一個(gè)空閑地址變成了16,下一個(gè)元素c的對(duì)界是416可以滿足,所以c放在了16,此時(shí)下一個(gè)空閑地址變成了20,下一個(gè)元素d需要對(duì)界1,也正好落在對(duì)界上,所以d放在了20,結(jié)構(gòu)體在地址21處結(jié)束。由于s1的大小需要是8的倍數(shù),所以21-23的空間被保留,s1的大小變成了24
?
對(duì)于s2,首先把a放到8的對(duì)界,假定是0,此時(shí)下一個(gè)空閑地址是1,下一個(gè)元素的對(duì)界也是1,所以b擺放在1,下一個(gè)空閑地址變成了2;下一個(gè)元素c的對(duì)界是4,所以取離2最近的地址4擺放c,下一個(gè)空閑地址變成了8,下一個(gè)元素d的對(duì)界是8,所以d擺放在8,所有元素?cái)[放完畢,結(jié)構(gòu)體在15處結(jié)束,占用總空間為16,正好是8的倍數(shù)。

?
這里有個(gè)陷阱,對(duì)于結(jié)構(gòu)體中的結(jié)構(gòu)體成員,不要認(rèn)為它的對(duì)齊方式就是他的大小,看下面的例子:

struct s1
{
char a[8];
};

struct s2
{
double d;
};

struct s3
{
s1 s;
char a;
};

struct s4
{
s2 s;
char a;
};

cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;

? s1
s2大小雖然都是8,但是s1的對(duì)齊方式是1s28double),所以在s3s4中才有這樣的差異。

?
所以,在自己定義結(jié)構(gòu)體的時(shí)候,如果空間緊張的話,最好考慮對(duì)齊因素來(lái)排列結(jié)構(gòu)體里的元素。