C/C++中基本數據類型所佔內存大小
C中不同數據類型所佔的字節大小,在不同的操作系統和編譯器下,是不同的,一般主要說gcc下,32位或64位系統的,紅色部分是32和64位系統不同的,做了個表如下:
數據類型 |
32位 |
64位 |
取值範圍(32位) |
char |
1 |
1 |
-128~127 |
unsigned char(當byte使用) |
1 |
1 |
0~255 |
short int /short |
2 |
2 |
–32,768~32,767 |
unsigned short |
2 |
2 |
0~65,535 |
int |
4 |
4 |
-2,147,483,648~2,147,483,647 |
unsigned int |
4 |
4 |
0~4,294,967,295 |
long int /long |
4 |
8 |
–2,147,483,648~2,147,483,647 |
unsigned long |
4 |
8 |
0~4,294,967,295 |
long long int/long long |
8 |
8 |
-9,223,372,036,854,775,808 ~9,223,372,036,854,775,807 |
指針 |
4 |
8 |
|
float |
4 |
4 |
3.4E +/- 38 (7 digits) |
double |
8 |
8 |
1.7E +/- 308 (15 digits) |
注意:
1. 求數組大小時,如果數組作爲參數傳遞時,退化爲指針,所以sizeof(arr)大小爲該系統下指針的大小
2. 對於C字符串,需要牢記C/C++中一個漢字佔兩個字節(Linux下3個字節)。
3. 求struct 或者 class 的大小時候,除了基本的數據類型大小,特別要考慮的是字節對齊問題,如果是C++的還涉及虛函數的虛表問題,需要加上虛表指針的大小,關於內存對齊的問題在別的博客會詳細寫。
關於數組,數組指針,指針數組稍微提一下:
關於sizeof求數組大小的,用代碼去gcc中驗證了下,說明下:
數組指針,本質是指向數組的指針,不管是指向什麼類型,幾維數組,sizeof返回的都是指針的大小;
只有正常創建數組 int arr[10],int arr[10][10],這樣sizeof(arr)求的是數組的大小,如下圖代碼中,fun函數中,sizeof(a)的大小爲指針的大小,數組作爲參數退化爲指針。
如下圖可以看到,gcc會警告,sizeof只會返回一個int 指針的值
如下圖代碼中,類似
int(*p)[10]; //p是指向一維數組int [10]的指針
int*p[10]; //p是一維的指針數組,數組的每個元素是指針
結果如下:
這裏解釋下,因爲是 64位系統,所以指針的大小是8,這裏a,j 是數組指針,然後d,f分別是一維數組,二維數組的指針,g,h也是,下面解釋一波他們的區別。只有b,c是指針數組。
這裏我除了輸出他們的內存大小,還有指針的值也就是他們指向的地址。
這裏可以看到,a,b,c,,d,e,f他們的地址,都是19335XXX,可以看出他們是在一塊內存中,這就是局部變量在棧區分配內存的,而g,h是b470XX, 因爲malloc是動態分配的,是在堆區分配的,所以是另外一塊內存。而且b,c的地址差值是240,差的就是b數組的大小。
順便提一下,棧區是向下增長的,可以驗證下(以下純屬個人興趣,看不同類型數組在棧區的起始地址):
四個數組的地址是連續的,且b和arr是向下增長的。
在看這裏,將最後的二維數組arr2改成一維數組後,arr2的地址是接在arr後面的(同類型是向上增長的),類型不一致後,另外起一段地址,是起低點的地址。