#1. 引言html
數據類型是程序的基礎,決定了編譯器以及運行時的各項操做解釋。在編譯時不一樣的變量應該分配多大的空間?在運行時對指針進行+1操做,指針應該跳幾個字節?在類型明確的狀況下,上述操做都有據可循,不會有歧義。C / C++ / JAVA / C#等語言都明肯定義了數據類型。我我的也是比較偏向於喜歡使用該類編程語言。編程
本章主要講述C++的自定義的內置類型,同時對類型描述const用法作一些總結。數組
#2. 原始內置類型 原始內置類型,書中原文爲Primitive Built-in Types,具體又分爲兩種 arithmetic types & void arithmetic types : 算術類型 bool, char,int, short, long,float,double等類型 void: 理解爲空類型,對於沒有返回的函數,經常將返回值寫爲void.服務器
對於char, short, int,long,long long類型,都是帶符號的整數類型數據,只是能夠表示的數據範圍不一樣,對應的數據長度也不一樣。下面是我在64爲服務器上運行的測試程序,能夠看到各種型數據的長度以及能夠表示的數據範圍也不同。我編寫了一個很簡單的測試程序,測試不一樣數據類型的數據長度以及對於整數,能夠表示的數據範圍。app
void typeSizeTest() { std::cout << "char size is: " << sizeof(char) << std::endl; std::cout << "int size is: " << sizeof(int) << std::endl; std::cout << "short size is: " << sizeof(short) << std::endl; std::cout << "long int size is: " << sizeof(long int) << std::endl; std::cout << "long size is: " << sizeof(long) << std::endl; std::cout << "long long size is: " << sizeof(long long) << std::endl; std::cout << "float size is: " << sizeof(float) << std::endl; std::cout << "double size is: " << sizeof(double) << std::endl; char maxChar = 0x7F, minChar = 0x80; printf("max char: %d, min Char: %d\n", maxChar, minChar); short maxShort = 0x7FFF, minShort = 0x8000; std::cout << "max Short: " << maxShort << " min Short: " << minShort << std::endl; int maxInt = 0x7FFFFFFF, minInt = 0x80000000; std::cout << "max Int: " << maxInt << " min Int: " << minInt << std::endl; long long maxLongLong = 0x7FFFFFFFFFFFFFFF, minLongLong = 0x8000000000000000; std::cout << "max LongLong: " << maxLongLong << " min LongLong: " << minLongLong << std::endl; }
char size is: 1 int size is: 4 short size is: 2 long int size is: 4 long size is: 4 long long size is: 8 float size is: 4 double size is: 8 max char: 127, min Char: -128 max Short: 32767 min Short: -32768 max Int: 2147483647 min Int: -2147483648 max LongLong: 9223372036854775807 min LongLong: -9223372036854775808
最大值符號位爲0,其餘全1
最小值符號位爲1,其餘全0編程語言
對於有符號的整數類型表達的範圍,此處csapp書中給出了很是好的解釋。 在40頁中有一個公式描述了補碼下的數據表示公式。函數
能夠看出,若是是正數,那麼w-1位爲0,其餘位全1便可。 若是是負數想要最小,w-1位爲1, 其餘位爲0,就能夠對於的數值最小。 經過這個公式看簡介明瞭。測試
float和double類型對應的數據位數以及精度不同。在個人測試機器中,float佔據4字節,double佔據8字節。阮一峯在他的博客中對浮點數在計算機中的存儲方式作了一個很是詳細的說明,簡單易懂,連接以下。 http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.htmlui
在C++中須要注意類型轉換的問題,其中可能會致使一些數據精度的損失以及可表示範圍的變化。根據業務判斷相關變量的可能範圍,選擇合適的類型。指針
const是一個限定符,常常用來描述不但願被改變的變量。主要有以下幾種用法:
這裏用來修飾一個普通變量,好比數組長度,任務數量等等,該變量一旦初始化後就不能改變。以下代碼就是一個示例。
const int bufSize = 256; int buf[bufSize]; for (int k = 0; k < bufSize; k++) { buf[k] = k; }
默認狀況下,const對象的做用域在文件內,若是須要跨文件使用,經過 extern關鍵字進行描述,達到跨文件使用的效果。
這種用法比較符合常規思惟,引用的類型和要引用的對象類型要匹配
const int a = 5; const int &b = a;
int c = 5; const int &d = c;
用一個常量引用去引用一個普通變量是能夠的,可是咱們沒法經過這個引用去修改這個變量。
double a = 3.14; double * const b = &a; *b = 5;
該代碼說明指針b一直指向a,不能夠從新指向其餘對象。但能夠經過指針修改a的內容
const double a = 3.14; const double *b = &a; const double c = 5; b = &c;
這裏指針指向誰能夠修改,可是你不能夠修改指針指向對象的內容。
const double a = 3.14; const double* const b = &a;
這種狀況下既不可讓b指向其餘對象,也不能夠經過b修改a的內容。雙重約束。
const int c = 5; int& d = c * 2; 錯誤信息: initial value of reference to none const must be an lvalue
這裏涉及到lvalue(左值), rvalue(右值)的問題,先搞明白這個概念再分析上面這個錯誤。每個C++表達式,要麼是左值,要麼是右值,左值能夠理解爲有名字的對象,好比說咱們本身定義的變量;右值能夠理解爲是臨時對象; 那麼上面例子中c*2其實結果只是一個臨時變量,是右值。可是編譯器認爲很是量引用要對應一個左值。匹配不上,因此報錯。
能夠進一步解釋,上述代碼能夠這麼寫:
const int c = 5; int temp = c * 2; int& d = temp; ``` temp只是一個臨時變量,若是d不是常量引用,說明咱們能夠經過d去修改臨時變量? 這種行爲在C++中是非法的。 ``` // 下面是MSDN關於左值右值的示例。 int main() { int i, j, *p; //屬於定義好的變量,有名稱,爲左值; // 正確, i 爲左值. i = 7; //錯誤: The left operand must be an lvalue (C2106). 7 = i; // C2106 j * 4 = 7; // C2106 // 正確: the dereferenced pointer is an lvalue. *p = i; const int ci = 7; //正確 // 錯誤: the variable is a non-modifiable lvalue (C3892). ci = 9; // C3892 // 正確: the conditional operator returns an lvalue. ((i < 3) ? i : j) = 7; } ``` [MSDN lvalue, rvalue解釋](https://msdn.microsoft.com/en-us/library/f90831hc.aspx)