1. 定義:
sizeof作用就是返回一個對象或者類型所佔的內存字節數。
它不是一個函數,其字節數的計算在程序編譯時進行的。
2. 語法格式:
(1)用於數據類型,使用形式: sizeof(type)
數據類型必須用括號括住。
sizeof(int)
(2)用於變量,使用形式: sizeof(varname) 或 sizeof varname
一般採用帶括號的方式。
int i; sizeof(i);
3. 返回結果:
sizeof int:4 sizeof short:2 sizeof long:4 sizeof float:4 sizeof double:8 sizeof char:1 /* 空類所佔空間爲1,單一繼承、多重繼承的空類所佔空間也是1,虛表(虛指針)所佔空間是4. */
(1)作用於指針:
在32位計算機中,一個指針變量的返回值必定是4(32/8),但是,在64位系統中指針變量的sizeof結果爲8。
(2)作用於數組:
數組的sizeof值等於數組所佔用的內存字節數,如:
int a[5]; sizeof(a) = 20; char b[] = "abc"; sizeof(b)=4;//末尾存在一個終止符 char str[20]="0123456789"; //strlen(str)=10(不含終止符);sizeof(str)=20;
(3)作用於函數參數:
void func(char a[3]) { int c=sizeof(a);//c=4 }
這裏函數參數a已不再是數組類型,而是變成了指針,相當於char* a,我們調用函數func時,程序不會在棧上分配一個大小爲3的數組,數組是“傳址”的,調用者只需將實參的地址傳遞過去,所以a自然爲指針類型(char*),c的值也就爲4。
(4)作用於聯合體:
結構體在內存組織上是順序式的,聯合體則是重疊式,各成員共享一段內存,所以整個聯合體的sizeof也就是每個成員sizeof的最大值。
union u{ char a; int b; double c; }; //sizeof(u)=8
(5)作用於結構體:
遵循兩個原則:
1).整體空間是 佔用空間最大的成員(的類型)所佔字節數的整倍數
2)數據對齊原則----內存按結構成員的先後順序排列,當排到該成員變量時,其前面已擺放的空間大小必須是該成員類型大小的整倍數,如果不夠則補齊,以此向後類推。
struct s1 { char a; double b; int c; char d; }; //sizeof(s1)=24; 各元素起始地址1-8-16-20,結構體在地址21處結束,大小需要是8的倍數24 struct s2 { char a; char b; int c; double d; };//sizeof(s2)=16 ;各元素起始地址 1-2-4-8;結構體在15處結束,大小需要是8的倍數16
在自己定義結構體的時候,如果空間緊張的話,最好考慮對齊因素來排列結構體裏的元素。
4. Sizeof與Strlen的區別與聯繫
(1)sizeof操作符的結果類型是size_t,它在頭文件中typedef爲unsigned int類型。其值在編譯時即計算好了,strlen的結果要在運行的時候才能計算出來,是用來計算字符串的長度。
(2) sizeof是運算符,strlen是函數。
(3)sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以“\0”結尾的。
(4)數組做sizeof的參數不退化,傳遞給strlen就退化爲指針了。
注意:
例1: strlen(char*)函數求的是字符串的實際長度,到遇到第一個'\0'結束,如果你只定義沒有給它賦初值,這個結果是不定的,它會從aa首地址一直找下去,直到遇到'\0'停止
char aa[10];cout<<strlen(aa)<<endl; //結果是不定的 char aa[10]={'\0'}; cout<<strlen(aa)<<endl; //結果爲0 char aa[10]="jun"; cout<<strlen(aa)<<endl; //結果爲3
而sizeof返回的是變量聲明後所佔的內存數,不是實際長度。
例2:
char* ss = "0123456789"; sizeof(ss); //結果 4 ; sizeof(*ss); //結果 1;*ss其實是獲得了字符串的第一位'0'所佔的內存空間; strlen(ss);//結果是10 ;