目錄
-
sizeof關鍵字
sizeof 爲C語言的一個主要關鍵字,而並非是一個函數,雖然其後經常會跟着一對括號,這就導致許多人認爲這是一個函數,進而產生誤解。
-
主要功能
求某一特定的變量、指針、結構體、枚舉、聯合體等所佔內存空間的大小。
-
常見用法
-
與基本數據類型的相關的內存空間大小的求解
sizeof(short) = ?
sizeof(int) = ?
sizeof(float) = ?
sizeof(double) = ?
sizeof(char) = ?
這些基本數類sizeof所求的內存空間大小受到不同系統的約束。例如:在64位系統下,其大小分別爲:
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(float) = 4
sizeof(double) = 8
-
與數組相關的內存空間大小的求解
int arr[64] = {0};
sizeof(arr) = ?
sizeof(arr[0]) = ?
sizeof(arr[64]) = ?
sizeof(&arr) = ?
sizeof(&arr[0]) = ?
int func (int arr[])
{
sizeof(arr) = ?
sizeof(&arr) = ?
}
-
在數組的定義處
- sizeof(arr) = 256, 是求數組的實際大小,即爲 64 * 4 = 256
- sizeof(arr[0]) = 4 ,是求數組的第一個元素所佔內存空間的大小,即和其定義時候的數據類型有關,這裏爲int 即爲4字節,若爲char即爲1個字節依次類推。
- sizeof(arr[64]) = 4,與sizeof(arr[0])類似;
- sizeof(&arr),則是求&arr所佔內存空間的大小,即求一個指針所佔內存空間的大小,會與系統是64位還是32位有關;若爲64位系統,則其大小位8字節,若爲32位系統,則其大小位4字節 。
- sizeof(&arr[0])與sizeof(&arr)類似,都是求解一個指針所佔內存空間的大小;
-
在具體函數的中
- sizeof(arr) = 8,因爲在函數傳參的時候數組實參會當指針形參來處理,即所傳的只是數組的首地址,所以sizeof(arr)的大小會與系統的位數有關;
- 其他的sizeof的相關求解不發生變化,例如sizeof(&arr) = 8;
-
運行實例
***********in arr:********** sizeof(arr) = 256 sizeof(&arr) = 8 sizeof(&arr[0]) = 8 sizeof(arr[64]) = 4 sizeof(arr[0]) = 4 *********in function:************** sizeof(arr) = 8 sizeof(&arr[0]) = 8
-
與指針的相關的變量所佔內存空間大小的求解
int p_int = NULL;
sizeof(p_int) = ?
sizeof(*p_int) = ?
- sizeof(p_int) 只要是指針其用sizeof來求某個指針變量所佔內存空間的大小都與系統的位數有關,若爲64位,則其大小永遠位8字節;若爲32位,則其大小永遠爲4字節。
- sizeof(*p_int) = 4,指針前加*表示取指針所指向的那段內存存放的值,即*p_int爲int類型,所以其大小爲4字節;
-
運行實例
sizeof(p_int) = 8 sizeof(*p_int) = 4
-
與結構體相關的變量所佔內存空間大小的求解
typedef struct student
{
char name[64];
int age;
unsigned int id;
char sex;
}student_t;
typedef struct zero
{
char name[64];
int age;
unsigned int id;
char sex;
}zero_t;
void test()
{
student_t st_student;
printf("sizeof(st_student) = %ld\n", sizeof(st_student));
zero_t st_aero;
printf("sizeof(st_zero) = %ld\n", sizeof(st_zero));
}
- sizeof(st_student)的大小爲多少呢? 是73?還是76?答案顯然不是83。因爲結果體會有字節對齊。正確答案爲86
- 結構體對齊的概念:即以結構體成員中佔內存最多的數據類型所佔的字節數爲標準,所有的成員在分配內存時都要與這個長度對齊。我們以上面這個程序爲例,結構體變量 student 的成員中佔內存最多的數據類型是 int 型,其佔 4 字節的內存空間,那麼所有成員在分配內存時都要與 4 字節的長度對齊。也就是說,雖然 char 只佔 1 字節,但是爲了與 4 字節的長度對齊,它後面的 3 字節都會空着。所以其大小都會4的整數倍。
- 如果我們定義一個空的結構體。那麼其大小會是多少呢? 0? 1? 還是其他?我們會理所當然認爲他的值應該是0,但是很可惜他不是0,而是1。但是我在Ubuntu的gcc的編譯器下測試結果爲0,在vc下測試結果爲1,也許他還會和編譯的實現相關吧。還有些編譯器如果你定義一個空的結構體他會不幹,拋錯。
- #pragma pack(x)我們也可以是#pragma pack(x)來改變結構體對齊的字節。例如:
#pragma pack (1) typedef struct student { char name[64]; int age; unsigned int id; char sex; }student_t; void test() { student_t st_student; printf("sizeof(st_student) = %ld\n", sizeof(st_student)); }
- 其輸出值爲 :
sizeof(st_student) = 73
-
運行實例
sizeof(st_student) = 76
sizeof(st_zero) = 0
-
與枚舉相關的變量所佔內存空間大小的求解
enum color
{
RED,
BLUE,
YELLOW
}en_color;
void test()
{
printf("sizeof(en_color) = %ld\n", sizeof(en_color));
}
- sizeof(en_color) ==> sizeof(int),永遠爲4,不管其內部有多少變量。枚舉類型,指一個被命名的整型常數的集合。即枚舉類型,本質上是一組常數的集合體,只是這些常數有各自的命名。枚舉類型,是一種用戶自定義數據類型。枚舉變量,由枚舉類型定義的變量。枚舉變量的大小,即枚舉類型所佔內存的大小。由於枚舉變量的賦值,一次只能存放枚舉結構中的某個常數。所以枚舉變量的大小,實質是常數所佔內存空間的大小(常數爲int類型,當前主流的編譯器中一般是32位機器和64位機器中int型都是4個字節),枚舉類型所佔內存大小也是這樣。
-
運行實例
sizeof(en_color) = 4
-
與聯合體(union)相關的變量所佔內存空間大小的求解
union { int age; char name[64]; char sex; }un_student; void test() { printf("sizeof(un_student) = %ld\n", sizeof(un_student)); }
- sizeof(un_student) = 64,因爲聯合體的大小爲其中定義的最大變量的大小。
-
運行實例
sizeof(un_student) = 64