**:
sizeof()功能:計算資料空間的位元組數
1.與strlen()比較
strlen()計算字元陣列的字元數,以"\0"為結束判斷,不計算為』\0』的陣列元素。
而sizeof計算資料(包括陣列、變數、型別、結構體等)所佔記憶體空間,用位元組數表示。
2.指標與靜態陣列的sizeof操作
指標均可看為變數型別的一種。所有指標變數的sizeof 操作結果均為4。
注意:
int
*p;sizeof
(p)=4;
但sizeof
(*p)相當於sizeof
(int
);
對於靜態陣列,sizeof可直接計算陣列大小;
例:
int a[10]
;char b=
"hello"
;sizeof
(a)等於4*10
=40;sizeof
(b)等於6
;
注意:陣列做型參時,陣列名稱當作指標使用!!
void
fun(
char p)
經典問題:
double*(
*a)[3]
[6];
cout<<
sizeof
(a)/ 4 a為指標
cout<<
sizeof
(*a)
/ 72 *a為乙個有3*6個指標元素的陣列
cout<<
sizeof(*
*a)/ 24 **a為陣列一維的6個指標
cout<<
sizeof(*
**a)
/ 4 ***a為一維的第乙個指標
cout<<
sizeof(*
***a)/ 8 ****a為乙個double變數
問題解析:
a是乙個很奇怪的定義,他表示乙個指向double*[
3][6
]型別陣列的指標。既然是指標,所以sizeof
(a)就是4。
既然a是執行double*[
3][6
]型別的指標,*a就表示乙個double*[
3][6
]的多維陣列型別,
因此sizeof
(*a)=3
*6*sizeof
(double*)
=72。
同樣的,*
*a表示乙個double*[
6]型別的陣列,所以sizeof(*
*a)=6*
sizeof
(double*)
=24。**
*a就表示其中的乙個元素,也就是double
*了,所以sizeof(*
**a)
=4。至於***
*a,就是乙個double了,
所以sizeof(*
***a)=
sizeof
(double)=
8。
3.格式的寫法
sizeof操作符,對變數或物件可以不加括號,但若是型別,須加括號。
4.使用sizeof時string的注意事項
string s=
"hello"
;sizeof
(s)等於string類的大小,sizeof
(s.c_str()
)得到的是與字串長度。
5.union 與struct的空間計算
總體上遵循兩個原則:
(1)整體空間是 占用空間最大的成員(的型別)所佔位元組數的整倍數
(2)資料對齊原則----記憶體按結構成員的先後順序排列,當排到該成員變數時,其前面已擺放的空間大小必須是該成員型別大小的整倍數,如果不夠則補齊,以此向後類推。。。。。
注意:陣列按照單個變數乙個乙個的擺放,而不是看成整體。如果成員中有自定義的類、結構體,也要注意陣列問題。
例:[引用其他帖子的內容]
因為對齊問題使結構體的sizeof變得比較複雜,看下面的例子:(預設對齊方式下)
struct s1
;struct s2
;cout<<
sizeof
(s1)
/ 24
cout<<
sizeof
(s2)
/ 16
同樣是兩個char型別,乙個int型別,乙個double型別,但是因為對齊問題,導致他們的大小不同。計算結構體大小可以採用元素擺放法,我舉例子說明一下:首先,cpu判斷結構體的對界,根據上一節的結論,s1和s2的對界都取最大的元素型別,也就是double型別的對界8。然後開始擺放每個元素。
對於s1,首先把a放到8的對界,假定是0,此時下乙個空閒的位址是1,但是下乙個元素d是double型別,要放到8的對界上,離1最接近的位址是8了,所以d被放在了8,此時下乙個空閒位址變成了16,下乙個元素c的對界是4,16可以滿足,所以c放在了16,此時下乙個空閒位址變成了20,下乙個元素d需要對界1,也正好落在對界上,所以d放在了20,結構體在位址21處結束。由於s1的大小需要是8的倍數,所以21-23的空間被保留,s1的大小變成了24。
對於s2,首先把a放到8的對界,假定是0,此時下乙個空閒位址是1,下乙個元素的對界也是1,所以b擺放在1,下乙個空閒位址變成了2;下乙個元素c的對界是4,所以取離2最近的位址4擺放c,下乙個空閒位址變成了8,下乙個元素d的對界是8,所以d擺放在8,所有元素擺放完畢,結構體在15處結束,占用總空間為16,正好是8的倍數。
這裡有個陷阱,對於結構體中的結構體成員,不要認為它的對齊方式就是他的大小,看下面的例子:
struct s1
;struct s2
;struct s3
;struct s4
;cout<<
sizeof
(s1)
/ 8
cout<<
sizeof
(s2)
/ 8
cout<<
sizeof
(s3)
/ 9
cout<<
sizeof
(s4)
/ 16;
s1和s2大小雖然都是8,但是s1的對齊方式是1,s2是8(double),所以在s3和s4中才有這樣的差異。
所以,在自己定義結構體的時候,如果空間緊張的話,最好考慮對齊因素來排列結構體裡的元素。
補充:不要讓double干擾你的位域
在結構體和類中,可以使用位域來規定某個成員所能占用的空間,所以使用位域能在一定程度上節省結構體占用的空間。不過考慮下面的**:
struct s1
;struct s2
;struct s3
;struct s4
;cout<<
sizeof
(s1)
/ 24
cout<<
sizeof
(s2)
/ 24
cout<<
sizeof
(s3)
/ 24
cout<<
sizeof
(s4)
/ 16
可以看到,有double存在會干涉到位域(sizeof的演算法參考上一節),所以使用位域的的時候,最好把float型別和double型別放在程式的開始或者最後。
sizeof
int:
4sizeof
short:2
sizeof
long:4
sizeof
float:4
sizeof
double:8
sizeof
char:1
sizeof p:
4sizeof word:
2sizeof dword:
4
sizeof 用法彙總
sizeof 功能 計算資料空間的位元組數 1.與strlen 比較 strlen 計算字元陣列的字元數,以 0 為結束判斷,不計算為 0 的陣列元素。而sizeof計算資料 包括陣列 變數 型別 結構體等 所佔記憶體空間,用位元組數表示。2.指標與靜態陣列的sizeof操作 指標均可看為變數型別的...
sizeof 用法彙總
sizeof 功能 計算資料空間的位元組數 1.與strlen 比較 strlen 計算字元陣列的字元數,以 0 為結束判斷,不計算為 0 的陣列元素。而sizeof計算資料 包括陣列 變數 型別 結構體等 所佔記憶體空間,用位元組數表示。2.指標與靜態陣列的sizeof操作 指標均可看為變數型別的...
sizeof 用法彙總
sizeof 功能 計算資料空間的位元組數 1.與strlen 比較 strlen 計算字元陣列的字元數,以 0 為結束判斷,不計算為 0 的陣列元素。而sizeof計算資料 包括陣列 變數 型別 結構體等 所佔記憶體空間,用位元組數表示。2.指標與靜態陣列的sizeof操作 指標均可看為變數型別的...