第二章
2.1 基本類型
- C++的基本類型分爲空類型和算術類型,空類型就是void,算術類型就是整型,字符型,浮點型,布爾型
- char分爲,unsigned char,signed char和char,其中char是有符號還是無符號取決於編譯器
- 對於無符號類型,如果賦值超過了其表示範圍,則結果爲該無符號類型所能表示的數值個數%賦值的數。
unsigned char c = -1;
//256%-1
cout<<int(c)<<endl;//輸出爲255
c=256;
//256%256
cout<<int(c)<<endl;//輸出爲0
這個其實算是總結規律了,超過其表示範圍的正數,從二進制角度來看其值全是000000000,所以超過其表示範圍的正數結果都是0。
而超過其表示範圍的負數,則要求得補碼,然後得到結果,總結除規律。
-1的源碼爲
1000 0001
補碼
1111 11111 =255
-
對於有符號類型,其值超過了表示範圍的話,是未定義行爲,即,有可能報錯,有可能產生垃圾值,還有可能忽略了超過的部分。
-
整型轉布爾類型的時候,值爲0,表示false,爲其他值表示true,包括負數。
-
字面值常量都對應着一個具體的基本類型,如果寫得超過了基本類型的表示範圍則會報錯。
2.2 變量
- 在任何函數體外定義的基本數據類型變量,其默認初始值爲0,但是在函數體中定義的基本數據類型變量默認初始值是未定義的。對於類的對象,則是由默認構造函數來決定
- extern int i;表示聲明一個來自外部的變量,但是如果寫成extern int i = 1; 則編程了定義一個變量。
2.3 複合類型
複合類型就是基本數據類型+一個*或者&,表示指針或者引用
- 可以使用int *a=0;來初始化指針,但是不可以使用
int zero = 0;
int* a = zero;
來初始化因爲我們不能用一個int對象來爲int變量賦值。
2. void ,可以指向任何類型的地址,但是其不能用來解引用
2.4 const限定符
- const定義的變量會在編譯時,把用到這個變量的地方都替換爲對應的值。
- const定義的變量,僅在文件內有效,如果我們在不同的文件中使用const int a,其實是定義了多個const變量!!!!!但是如果我們想在其他的文件中也使用同一個const變量,那麼在聲明這個const變量的時候,需要使用
1.cpp
extern const string hello="world";
而在調用的地方使用來調用
2.cpp
extern const string hello;
拓展:
對於全局的非const變量,他的作用域是整個程序,所以其他的文件都可以訪問到這個全局的非const變量。
我們要使用這個全局的非const遍歷時,使用
1.cpp
int dali=233;
2.cpp
extern int dali;
來調用
如果在其他文件中,以下方法,則程序會報錯,因爲重定義了。
2.cpp
extern int ali=666;
或者
int ali=66
- 不可以使用普通引用來綁定一個字面值常量,但是可以使用一個const引用來綁定字面值常量。
一種理解角度是:因爲const定義的變量在編譯時將在調用處替換爲其所存儲的值,雖然將其綁定爲一個字面值常量,但是在編譯時又被替換爲字面值了,所以這種綁定方式合法。
- const分爲低層const和頂層const,頂層const在賦值時,const可以被忽視。但是低層const不能被忽視。其中指針常量是低層const,所有的const引用都是低層const
const int i=1;//頂層
int j = i;//不報錯
const int* p = nullptr;
int* q = p;//不報錯
int* const p = nullptr;
int *q = p;//報錯
int v= 123;
const int& i = v;
int& j = i;//報錯
注意對於const引用都是低層const,其const不能忽略的前提是,初始化的對象還是const對象,如果初始化的對象是一個普通的變量,是可以的。
int v= 123;
const int& i = v;
int j = i;//合法
5.在編譯時就確定了取值和取值不會改變的變量叫做常量表達式。常量表達式要用const來修飾,但是使用const修飾的變量,不一定是常量表達式。
比如
const int v= get_data();
該函數只有在運行時才能確定取值,所以v,不是常量表達式。
可以使用constextpr來聲明一個常量表達式,讓編譯器來驗證這個變量是否是常量表達式。
constexpr int* p = nullptr;
和
const int*p = nullptr;
的結果是一頁的。
2.5 處理類型
- 對於頂層const,auto推導類型時會直接忽略,但是對於低層const則會保留。
const int* p = nullptr;//低層const
auto a = p;//a的類型爲const int*
- decltype 類型指示符,用來獲取變量的類型,其會原樣的保留變量的類型。對於頂層const和低層const他都會保留。
對於一個指針解引用獲取的類型將是變量的引用的類型。因爲*p可以改變變量本身,所以得到的類型也將是引用類型。
如果decltype()中的是一個普通變量,那麼得到的類型就是變量的類型,但是如果裏面是一個表達式,那麼decltype()得到的類型取決於表達式是左值還是右值,如果表達式返回的結果是左值,那麼得到的結果是變量類型的引用。
decltype(a=b)
一個特殊的情況是,如果對一個變量使用()括起來,得到的結果也是這個變量類型的引用。
decltype並不會計算其內部的表達式,而是推斷表達式指向的結果,這和sizeof()運算符一樣。