天天看點

C++ 基本資料類型 的 位元組數

閑聊c/c++: 各平台下基本資料類型的位元組長度:​​https://www.jianshu.com/p/1116616940bb​​

32位 與 64位系統 資料類型

不同的平台上對不同的資料類型配置設定的位元組數是不同的,一般的,資料類型的位元組數是由編輯器決定的(編譯期間決定資料類型長度)。

簡單來說,平台就是 CPU+OS+Compiler,cpu的位是指一次性可處理的資料量是多少,1位元組=8位,32位處理器可以一次性處理4個位元組的資料量,依次類推。32位作業系統針對的32位的CPU設計。64位作業系統針對的64位的CPU設計。是以平台是三者的組合,它們的位元組長相同時,效率最高。

下面是32位系統與64位系統各資料類型對比:

C++ 基本資料類型 的 位元組數

除了 * 随作業系統子長變化而變化外,其他的都固定不變(32位和64位相比)

float 與 double 的 範圍 和 精度

範圍 :

        float和double的範圍是由指數的位數來決定的。 

        float的指數位有8位,而double的指數位有11位,分布如下: 

float: 

        1bit(符号位) 8bits(指數位) 23bits(尾數位) 

double: 

        1bit(符号位) 11bits(指數位) 52bits(尾數位) 

于是,float 的指數範圍為-127~+128,而 double 的指數範圍為-1023~+1024,并且指數位是按補碼的形式來劃分的。 

其中負指數決定了浮點數所能表達的絕對值最小的非零數;而正指數決定了浮點數所能表達的絕對值最大的數,也即決定了浮點數的取值範圍。 

float 的範圍為-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;

double 的範圍為-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。

精度 

float和double的精度是由尾數的位數來決定的。浮點數在記憶體中是按科學計數法來存儲的,其整數部分始終是一個隐含着的“1”,由于它是不變的,故不能對精度造成影響。 

float:2^23 = 8388608,一共七位,這意味着最多能有7位有效數字,但絕對能保證的為6位,也即 float 的精度為6~7位有效數字; 

double:2^52 = 4503599627370496,一共16位,同理,double 的精度為15~16位。

1. 基本資料類型大小的對比

關于資料類型的大小,總是記不住,這裡也算有個記錄,順便看一下 32位 和 64位 之間的差别:

32 和 64  選擇

C++ 基本資料類型 的 位元組數

測試程式

#include "stdafx.h"  
#include <iostream>  
#include <string>  
using namespace std;  
  
  
//main  
int _tmain(int argc, _TCHAR* argv[])  
{  
    cout << "sizeof(char):" << sizeof(char) << endl;  
    cout << "sizeof(short):" << sizeof(short) << endl;  
    cout << "sizeof(int):" << sizeof(int) << endl;  
    cout << "sizeof(long):" << sizeof(long) << endl;  
    cout << "sizeof(long long):" << sizeof(long long) << endl;  
    cout << "sizeof(unsigned int):" << sizeof(unsigned int) << endl;  
    cout << "sizeof(float):" << sizeof(float) << endl;  
    cout << "sizeof(double):" << sizeof(double) << endl;  
    void* pointer;  
    cout << "sizeof(pointer):" << sizeof(pointer) << endl;  
  
    system("pause");  
    return 0;  
}      

 win32下:

sizeof(char):1
sizeof(short):2
sizeof(int):4
sizeof(long):4
sizeof(long long):8
sizeof(unsigned int):4
sizeof(float):4
sizeof(double):8
sizeof(pointer):4      
C++ 基本資料類型 的 位元組數

x64下:

sizeof(char):1
sizeof(short):2
sizeof(int):4
sizeof(long):4
sizeof(long long):8
sizeof(unsigned int):4
sizeof(float):4
sizeof(double):8
sizeof(pointer):8      
C++ 基本資料類型 的 位元組數

32位 和 64位 系統在Windows下基本資料類型的大小都是一樣的。隻有指針的大小不一樣!32位指針大小為4byte,而64位的指針大小為8byte。

注:Linux下,long 型是64位的,這一點是和Windows不同的地方。

PS:64位系統下是可以運作32位程式的。但是反過來的話是運作不了的。

2.為什麼Windowsx64下 long 也為 4 byte?

我們知道,正常标準的話,long應該也是64位即8byte。但是在Windows下,我們的結果卻是4byte。為什麼會這樣呢?這裡引用MSDN的一段關于x64下的解釋:

Platform SDK: 64-bit Windows Programming

Abstract Data Models

Every application and every operating system has an abstract data model. Many applications do not explicitly expose this data model, but the model guides the way in which the application's code is written. In the 32-bit programming model (known as the ILP32 model), integer, long, and pointer data types are 32 bits in length. Most developers have used this model without realizing it. For the history of the Win32? API, this has been a valid (although not necessarily safe) assumption to make.

In 64-bit Microsoft? Windows?, this assumption of parity in data type sizes is invalid. Making all data types 64 bits in length would waste space, because most applications do not need the increased size. However, applications do need pointers to 64-bit data, and they need the ability to have 64-bit data types in selected cases. These considerations led to the selection of an abstract data model called LLP64 (or P64). In the LLP64 data model, only pointers expand to 64 bits; all other basic data types (integer and long) remain 32 bits in length.

Initially, most applications that run on 64-bit Windows will have been ported from 32-bit Windows. It is a goal that the same source, carefully written, should run on both 32- and 64-bit Windows. Defining the data model does not make this task easier. However, ensuring that the data model affects only pointer data types is the first step. The second step is to define a set of new data types that allow developers to automatically size their pointer-related data. This allows data associated with pointers to change size as the pointer size changes from 32 bits to 64 bits. Basic data types remain 32 bits in length, so there is no change in the size of data on the disk, data shared over a network, or data shared through memory-mapped files. This relieves developers of much of the effort involved in porting 32-bit code to 64-bit Windows.

These new data types have been added to the Windows API header files. Therefore, you can start using the new types now. For more information, see The New Data Types.

簡單解釋一下:

我們程式設計時很少關注資料類型真正的大小,畢竟即使不關注這個也可以程式設計,而且我們習慣了Win32,到64位下,隻有指針因為尋址需要是必須變成64位的,64位的指針尋址範圍是0~2^64-1,而其他的資料類型基本已經夠用,如果把所有資料類型變成64位,明顯是浪費空間。再者,為了讓32位和64位程式相容運作,能少修改還是少修改,是以Windows僅将指針大小進行了修改。這樣,程式可以相容運作。

3.指針的大小

我們看看指針到底有多大?指向不同類型對象的指針大小是不是會有不同?看一個小例子:

#include "stdafx.h"  
#include <iostream>  
#include <string>  
using namespace std;  
  
class Test  
{  
    int num;  
    string name;  
};  
//一個函數指針  
typedef void(*pFunc)(void);  
void PrintHello(void)  
{  
    cout << "hello world" << endl;  
}  
//main  
int _tmain(int argc, _TCHAR* argv[])  
{  
    int* pInt;  
    void* pVoid;  
    Test* pTest = new Test();  
    pFunc pfunc = PrintHello;  
    cout << "sizeof(pInt):" << sizeof(pInt) << endl;  
    cout << "sizeof(pVoid):" << sizeof(pVoid) << endl;  
    cout << "sizeof(pTest):" << sizeof(pTest) << endl;  
    cout << "sizeof(pFunc):" << sizeof(pfunc) << endl;  
  
    system("pause");  
    return 0;  
}      

結果:

Win32下:

sizeof(pInt):4
sizeof(pVoid):4
sizeof(pTest):4
sizeof(pFunc):4
請按任意鍵繼續. . .      

x64下:

sizeof(pInt):8
sizeof(pVoid):8
sizeof(pTest):8
sizeof(pFunc):8
請按任意鍵繼續. . .      

可見,不管指針指向張三李四還是王二麻子,都是一樣大的。能夠影響指針大小的,還是位數。32位下指針大小為4,64位下指針的大小為8.

4.string的大小

關于string的大小,我們寫一小段代碼測試一下:

#include "stdafx.h"  
#include <iostream>  
#include <string>  
using namespace std;  
//main  
int _tmain(int argc, _TCHAR* argv[])  
{  
    string empty("");  
    string name("hehe");  
    string longstr("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");  
    cout << sizeof(empty) << endl;  
    cout << sizeof(name) << endl;  
    cout << sizeof(longstr) << endl;  
    cout << sizeof(string) << endl;  
    system("pause");  
    return 0;  
}      

結果:

Win32下:

28
28
28
28
請按任意鍵繼續. . .      

x64下:

32
32
32
32
請按任意鍵繼續. . .      

32位 和 64位下string 差 4byte,其實就是一個指針的差别。

string 内部并不儲存字元串本身,而是儲存了一個指向字元串開頭的指針。