2.1 基本內(nèi)置類型
| 算數(shù)類型 | 空類型 |
|---|---|
| 整型(包括字符型,布爾型) 浮點數(shù) |
2.1.1 算數(shù)類型
- 空類型(void):無值無操作,不能定義void類型變量
- 字符類型:char為UTF-8編碼,wchar_t是確保機器可以存儲及其最大擴展字符集中的任何字符的寬字符,char16_t和char32_t對應(yīng)Unicode字符集
- 內(nèi)置類型的機器實現(xiàn):地址表示比特串開始位置,類型決定了數(shù)據(jù)所占的比特位數(shù)及如何解釋其內(nèi)容
- 浮點數(shù):float和double分別有7和16個有效位,通常選用double,避免float的低精度及l(fā)ong double的低效率
2.1.2 類型轉(zhuǎn)換
- 給無符號類型一個超出他表示范圍的值時,結(jié)果是初始值對無符號類型表示數(shù)值總數(shù)取模后的余數(shù).
- 有無符號類型混用:表達式中同時包含帶符號和無符號類型,帶符號數(shù)會自動轉(zhuǎn)為無符號數(shù)
2.1.3 字面值常量
- 整型字面值:十進制字面值默認為帶符號數(shù),是int/long/long long 中能容納其值且尺寸最小。八進制(0開頭)和十六進制(0x開頭)則是int/unsigned int/unsigned long/long long/unsigned long long中尺寸最小者
- 浮點型字面值:小數(shù)或科學(xué)計數(shù)法形式的指數(shù),默認類型double
- 字符串字面值:類型實際是由常亮字符構(gòu)成的數(shù)組,編譯器在每個字符串結(jié)尾添加空字符'\0
- 字符前綴與類型:u(char16_t),U(char32_t),L(wchar_t),u8(char)
- 泛化的轉(zhuǎn)義序列:\x 后跟十六進制數(shù)字,或\ 后跟1到3位八進制數(shù)字(8進制數(shù)超過3個,只有前3個數(shù)字與\構(gòu)成轉(zhuǎn)義序列),可像普通字符一樣使用.
2.2 變量
2.2.1 變量定義
- 對象:是指一塊能存儲數(shù)據(jù)并具有某種類型的內(nèi)存空間.
- c++語言中,初始化和賦值是兩個完全不同的操作.
- 列表初始化:使用花括號初始化,當(dāng)存在丟失信息風(fēng)險時編譯器將報錯,而使用()可以執(zhí)行但可能發(fā)生信息丟失
例如:
long double ld =3.1415926536;
int a{ld}, b={ld}; //錯誤:轉(zhuǎn)換為執(zhí)行,因為存在丟失信息的危險
int c(ld), d=ld; //正確:轉(zhuǎn)換執(zhí)行,且確實丟失了部分 - 初始化:定義在任何函數(shù)之外的變量被初始化為0,每個類決定各自的初始化對象方式。而定義在函數(shù)體內(nèi)部的內(nèi)置變量類型將不初始化,試圖訪問未初始化的值將引發(fā)未定義行為
2.2.2 變量聲明和定義的關(guān)系
聲明:規(guī)定變量的類型和名字,使得名字為程序所知,
定義:負責(zé)創(chuàng)建與名字關(guān)聯(lián)的實體,并申請存儲空間.
- 變量聲明規(guī)定了變量的類型和名字,在這一點上定于預(yù)支相同.但是處置之外,定義還申請了存儲空間,也可能回味變量賦一個初值.
- 如果向聲明一個變量而非定義它,就在變量名前添加關(guān)鍵字extern,而且不要顯示地初始化
2.3 復(fù)合類型
復(fù)合類型是指基于其他類型定義的類型,例如引用和指針.
2.3.1 引用
- 引用:為對象起的別名(不是對象),定義時必須初始化,不可定義引用的引用,定義了一個引用后,對其進行的所有操作都是在與之綁定的對象上進行的。一旦綁定了就不能再綁定到另外的對象.
- 引用只能綁定在對象上,而不能預(yù)字面值或某個表達式的計算結(jié)果綁定在一起.
2.3.2 指針
- 指針:指向某個對象(引用不是對象,所以不能定義指向引用的指針),定義時無需賦值,本身就是對象,對指針使用解引用符*可訪問該對象
- 引用/指針類型匹配:除兩種特例(const可綁定非const,基類可綁定派生類)外,指針和引用的類型都需要與之綁定的對象嚴(yán)格匹配。
- 指針值狀態(tài):指向一個對象、指向?qū)ο蟮南乱粋€緊鄰空間位置、空指針、無效指針(訪問或拷貝都會出錯)
- 空指針:不指向任何對象,對象數(shù)據(jù)為0d
int *p1=nullptr;
int *p1=0;
int *p1=NULL; (c++不支持void*的隱式轉(zhuǎn)換,所以NULL的值就是0,而不是c中的(void*)0 ) - nullptr:一個特殊類型的字面值,可以理解為0指針,它可以被轉(zhuǎn)換成任意其他的指針類型。
- 初始化指針:建議用已定義對象或nullptr或0初始化所有指針,把任何int型變量(即使值為0)賦值給指針是錯誤的。
- void*指針:可存放任意對象的地址,但不能直接操作其所指對象。(因為我們不知道對象類型)一般用來和別的指針比較、作為函數(shù)的輸入輸出或者賦給另外一個void*指針。
2.3.3 理解復(fù)合類型的聲明
- 復(fù)合類型判斷:從右向左閱讀復(fù)雜的指針或引用的聲明語句,離變量名越近的符號對變量的類型有越直接的影響
指向指針的引用 int *p; int *&r=p;
2.4 const限定符
- 多文件共享const:默認情況下,const對象僅在文件內(nèi)有效。所以為了在多文件下共享const對象,不管聲明還是定義都要添加關(guān)鍵字extern
2.4.1 const的引用
- 初始化對const的引用:引用的類型必須與其所引用的對象一致,但是有兩種例外,第一種就是在初始化變量引用時允許任何表達式作為初始值,只要該表達式結(jié)果可以轉(zhuǎn)化為引用類型的臨時量對象。(const int 可以綁定到int 但是不能綁定到float )
2.4.2 指針和const
- 指向常量的指針:不去改變所指對象的值,而該對象若不是常量對象則其值通過其他方式改變。(所謂指向常亮的指針,僅僅要求不能通過該指針改變對象的值,而沒有規(guī)定那個對象的值不能通過其他途徑改變)
- 指針類型必須與其所指向的對象的類型一致,但有兩個例外。第一種是允許令一個指向常量的指針指向一個非常量的指針。
- const指針:常量指針必須初始化,它的值(也就是存放在對象中的地址)不能再改變。表示不變的是指針本身而非指針指向的對象
2.4.3 頂層const
- 頂層/底層const:頂層const表示指針本身是常量,底層const表示指針?biāo)傅膶ο笫浅A浚粓?zhí)行拷貝操作時,拷入拷出對象必須具有相同的底層const資格,或能夠強制轉(zhuǎn)換。
- 更一般的,頂層const可以表示任意的對象是常亮。底層const則與指針和引用等復(fù)合類型的基本類型有關(guān)。比較特殊的是,指針類型既可以是頂層const也可以指底層const。(總的來說就是分為一般類型和復(fù)合類型,一般類型都是頂層const,只有在復(fù)合類型時,才有底層const)
2.4.4 constexpr 和常量表達式
- 常量表達式:數(shù)據(jù)類型和初始值都需要是常量類型,值不會改變并在編譯過程就能得到計算結(jié)果。
- constexpr變量:一定是常量,必須用常量表達式(字面值類型,包括算術(shù)類型、引用、指針)或constexpr函數(shù)(足夠簡單編譯時可計算結(jié)果)初始化。
- 指針和constexpr:在constexpr聲明中如果定義了一個指針,限定符constexpr僅對指針有效,與指針?biāo)笇ο鬅o關(guān)。
2.5 處理類型
2.5.1 類型別名
- 指針、常量與類型別名:typedef char *pstring; const pstring cstr = 0;,與const pstring *cstr不等價,前者的cstr是指向char的常量指針,后者中cstr是一個指針,它的對象是指向char的常量指針。(pstring 是一個指向char 的指針,已經(jīng)有了指向類型了,然后const是來修飾這個psting表示的指針的,所以cstr是指向char的常量指針)
2.5.2 auto類型說明符
- 類型說明符auto:讓編譯器通過初始值推算變量類型,并賦諸該值;忽略頂層const,保留底層const。auto定義的變量必須有初始值。
2.5.2 decltype類型指示符
- 類型指示符decltype:讓編譯器通過初始值推算變量類型,但不用該初始值賦值;包含頂層const,解引用、(())、賦值產(chǎn)生的引用都會判為引用類型。
- 預(yù)處理器:在編譯前執(zhí)行的一段程序,功能有替換#include的頭文件,以及頭文件保護符避免重復(fù)定義實體。