C++定義了一套包括算術(shù)類(lèi)型(arithmetic type) 和 空類(lèi)型(void)在內(nèi)的基本數(shù)據(jù)類(lèi)型。算數(shù)類(lèi)型包括字符型、整型、布爾型和浮點(diǎn)型??疹?lèi)型不對(duì)應(yīng)具體的值,大多數(shù)情況下當(dāng)函數(shù)不返回任何值的時(shí)候作為返回類(lèi)型。
算數(shù)類(lèi)型分為兩類(lèi):整型(字符型、布爾型,整型)和 浮點(diǎn)型。不同類(lèi)型所占字節(jié)的大小在不同的機(jī)器上有所差異
類(lèi)型 | 含義 | 最小尺寸 |
---|---|---|
bool | 布爾類(lèi)型 | 未定義 |
char | 字符 | 8位 |
wchar_t | 寬字符 | 16位 |
char16_t | Unicode 字符 | 16位 |
char32_t | Unicode 字符 | 32位 |
short | 短整型 | 16位 |
int | 整型 | 16位 |
long | 長(zhǎng)整型 | 32位 |
long long | 長(zhǎng)整型 | 64位 |
float | 單精度浮點(diǎn)數(shù) | 6位有效數(shù)字 |
double | 雙精度浮點(diǎn)數(shù) | 10位有效數(shù)字 |
long double | 拓展精度浮點(diǎn)數(shù) | 10位有效數(shù)字 |
有符號(hào)類(lèi)型和無(wú)符號(hào)類(lèi)型
對(duì)象類(lèi)型定義了對(duì)象能包含的數(shù)據(jù)和能參與的運(yùn)算,其中一種運(yùn)算被大多數(shù)類(lèi)型支持,就是將對(duì)象從一種給定的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為另一種相關(guān)類(lèi)型。
bool b = 42; // b 為true
int i = b; // i 為 1
i = 3.14; // i 為 3
double pi = i; //pi 為 3.0
unsigned char c = -1; //c 為 255
signed char c2 = 256;//c2 未定義
含有無(wú)符號(hào)類(lèi)型的表達(dá)式:
unsigned u = 10;
int i = -42;
cout<< i + i<< endl; //84
cout<< u + i<< endl; //4294967264 即 -32 的二進(jìn)制表示 看作無(wú)符號(hào)數(shù) 就是4294967264
當(dāng)一個(gè)表達(dá)式中既有無(wú)符號(hào)數(shù)又有int值時(shí),這個(gè)int值就會(huì)轉(zhuǎn)換成無(wú)符號(hào)數(shù)。負(fù)數(shù)轉(zhuǎn)換為無(wú)符號(hào)數(shù)類(lèi)似于直接給無(wú)符號(hào)數(shù)賦一個(gè)負(fù)值。
**注意:**如果在循環(huán)中使用無(wú)符號(hào)數(shù),可能會(huì)造成死循環(huán)
//會(huì)一直死循環(huán)下去
for (unsigned u = 10; u >= 0; u--) {cout<< u<< endl;
}
3.字面值常量一個(gè)形如42的值被稱(chēng)為字面值常量,這樣的值一看就知。每一個(gè)字面值常量都對(duì)應(yīng)一種數(shù)據(jù)類(lèi)型,字面值常量的形式和值決定了它的數(shù)據(jù)類(lèi)型。
我們可以將整型字面值寫(xiě)作10進(jìn)制數(shù),8進(jìn)制數(shù) 或 16進(jìn)制數(shù)。默認(rèn)情況下 10進(jìn)制字面值是有符號(hào)數(shù),8進(jìn)制數(shù) 和 16進(jìn)制字面值既可能是有符號(hào)數(shù)也可能是無(wú)符號(hào)數(shù)。short沒(méi)有對(duì)應(yīng)的字面值
int a = 1;//10進(jìn)制數(shù)
int b = 02;//8進(jìn)制數(shù)
int c = 0x123;//16進(jìn)制數(shù)
由單引號(hào)括起來(lái)的是char字面值,雙引號(hào)括起來(lái)的零個(gè)或多個(gè)字符稱(chēng)為字符串字面值。字符串字面值的類(lèi)型實(shí)際上是由常量字符構(gòu)成的數(shù)組array。
char c = 'a'; //字符字面值
string s = "abcd"; //字符串字面值
true 和 false 是布爾型的字面值。nullptr 是 指針字面值。
bool ok = true;
int * ptr = nullptr;
二、變量變量提供一個(gè)具有名字的,可供程序操作的內(nèi)存空間。C++中每一個(gè)變量都有其數(shù)據(jù)類(lèi)型,數(shù)據(jù)類(lèi)型決定著變量所占內(nèi)存空間的大小和布局方式,該內(nèi)存空間能存儲(chǔ)值的范圍,以及變量能參與的運(yùn)算。
1. 變量定義形式:類(lèi)型說(shuō)明符 + 一個(gè)或者多個(gè)變量名組成的列表(其中變量名以逗號(hào)分隔)
什么是對(duì)象?
1.初始值通常情況下,對(duì)象是指一塊能存儲(chǔ)數(shù)據(jù) 并且 具有某種類(lèi)型的內(nèi)存空間
當(dāng)對(duì)象在創(chuàng)建時(shí)獲得了一個(gè)特定的值,這個(gè)對(duì)象就被初始化了。
在C++中,初始化是一個(gè)非常復(fù)雜的問(wèn)題,實(shí)際上初始化和賦值是兩個(gè)完全不同的操作。初始化不是賦值,初始化的含義是創(chuàng)建對(duì)象時(shí)賦予其一個(gè)初始值,而賦值的含義是把對(duì)象的當(dāng)前值擦除,而以一個(gè)新的值來(lái)替代。
作為C++ 11 的標(biāo)準(zhǔn),可以使用花括號(hào)來(lái)初始化變量,這種初始化形式稱(chēng)為列表初始化。
//以下四種方式都可以初始化
int a = 10;
int b(10);
int c = {10 };
int d{10 };
注意:如果使用列表初始化 并且 初始化存在丟失信息的風(fēng)險(xiǎn)時(shí),編譯器會(huì)報(bào)錯(cuò)
long double ld = 3.14159;
int a{ld }, b = {ld }; //編譯器報(bào)錯(cuò)
int c(ld), d = ld; //正常執(zhí)行,丟失了小數(shù)部分的精度
3.默認(rèn)初始化如果定義變量的時(shí)候沒(méi)有指定初始值,則變量被默認(rèn)初始化,此時(shí)變量也被賦予默認(rèn)值。
建議初始化每一個(gè)內(nèi)置類(lèi)型的變量
2.變量聲明和定義的關(guān)系C++支持分離式編譯機(jī)制,該機(jī)制允許將程序分割為若干個(gè)文件,每一個(gè)文件都可以被獨(dú)立編譯。
如果想聲明一個(gè)變量而不是定義,可以在變量名前面添加 extern ,并且不要顯式的初始化變量
extern int a; //聲明 a
int b; //聲明 并且 定義 b
extern 語(yǔ)句如果包含初始值就不再是聲明了,而變成定義。如果在函數(shù)體內(nèi)部,初始化一個(gè)由extern標(biāo)記的變量,會(huì)引起錯(cuò)誤:
void test2() {extern int a; //聲明 a
int b; //聲明 并且 定義 b
extern int c = 20; //報(bào)錯(cuò)
}
注意:變量只能被定義一次,但是可以被聲明多次
如果要在多個(gè)文件中使用同一個(gè)變量就必須將聲明和定義分開(kāi)。變量的定義只能出現(xiàn)在一個(gè)文件中,而其他用到該變量的文件必須對(duì)其進(jìn)行聲明,絕對(duì)不能重復(fù)定義。
C++是一種靜態(tài)類(lèi)型語(yǔ)言,其含義是在編譯階段檢查類(lèi)型。其中,檢查類(lèi)型的過(guò)程稱(chēng)為類(lèi)型檢查。
3.標(biāo)識(shí)符C++的標(biāo)識(shí)符由字母、數(shù)字和下劃線(xiàn)組成,其中必須以字母或者下劃線(xiàn)開(kāi)頭。用戶(hù)自定義的標(biāo)識(shí)符中不能連續(xù)出現(xiàn)兩個(gè)下劃線(xiàn),也不能以下劃線(xiàn)緊鄰大寫(xiě)字母開(kāi)頭。
變量名定義規(guī)范:
作用域是程序的一部分,在其中變量名有其特定的含義。C++中大多數(shù)作用域都以花括號(hào)分隔。
變量名的有效區(qū)域 始于變量名的聲明語(yǔ)句,以聲明語(yǔ)句所在的作用域末端為結(jié)束。
如果函數(shù)有可能用到某全局變量,則不宜再定義一個(gè)同名的局部變量
三、復(fù)合類(lèi)型復(fù)合類(lèi)型是指基于其他類(lèi)型定義的類(lèi)型。本節(jié)介紹其中的兩種:引用 和 指針
1. 引用引用為對(duì)象去了另一個(gè)名字,引用類(lèi)型引用另外一種類(lèi)型(這里的引用指的是左值引用)。定義引用時(shí),程序把引用和它的初始值綁定到一起,而不是將初始值拷貝給引用。
int val = 10;
int& refval = val; //refval 是 val的另外一個(gè)名字
注意:引用并不是對(duì)象。相反,他只是為一個(gè)已經(jīng)存在的對(duì)象所起的另外一個(gè)變量名。因?yàn)橐貌皇菍?duì)象,所以不能定義引用的引用
1.引用的定義允許再一條語(yǔ)句中定義多個(gè)引用,其中每一個(gè)引用標(biāo)識(shí)符都必須&開(kāi)頭。除了兩種特殊情況外,其他所有引用的類(lèi)型都要和與之綁定的對(duì)象嚴(yán)格匹配。并且,引用只能綁定在對(duì)象上,而不能與字面值或某個(gè)表達(dá)式的計(jì)算結(jié)果綁定到一起。
int& ref = 10; //錯(cuò)誤:引用類(lèi)型的初始值必須是一個(gè)對(duì)象
double dval = 3.14;
int& ref2 = dval; //錯(cuò)誤:此處引用類(lèi)型的初始值必須是int類(lèi)型的
2.指針指針是指向另一種類(lèi)型的復(fù)合類(lèi)型。和引用類(lèi)似,指針也實(shí)現(xiàn)了對(duì)其它對(duì)象的間接訪(fǎng)問(wèn)。不同點(diǎn):指針本身也是一個(gè)對(duì)象,允許對(duì)指針進(jìn)行賦值和拷貝操作,而且在指針的生命周期內(nèi)他可以先后指向幾個(gè)不同的對(duì)象;指針不用再定義的時(shí)候賦初始值。
1.獲取對(duì)象的地址指針存放某個(gè)對(duì)象的地址,要想獲取該地址,需要使用取地址符&:
int a = 10;
int* p = &a; //p存放變量a的地址 或者說(shuō) p 是指向變量a 的指針
因?yàn)橐貌皇菍?duì)象,沒(méi)有實(shí)際地址,所以不能定義指向引用的指針
除了兩種特殊的情況外,其他所有指針的類(lèi)型都要和它所指向的對(duì)象的類(lèi)型匹配:
double dval = 3.14;
double* pd = &dval;
double* pd2 = pd;
int* pi = pd; //錯(cuò)誤:指針pi的類(lèi)型和pd的類(lèi)型不匹配
pi = &dval; //錯(cuò)誤:試圖把double類(lèi)型對(duì)象的地址賦給int型指針
2.指針值指針的值(地址)應(yīng)該屬于以下4種狀態(tài)之一:
試圖拷貝 或者以其他的方式訪(fǎng)問(wèn)無(wú)效指針的地址都會(huì)引發(fā)錯(cuò)誤
雖然第二種和第三種指針的形式是有效的,但是這些指針沒(méi)有指向任何具體的對(duì)象,所以試圖訪(fǎng)問(wèn)此類(lèi)指針的對(duì)象的行為是不被允許的
3.利用指針訪(fǎng)問(wèn)對(duì)象如果指針指向了一個(gè)對(duì)象,則允許使用 解引用符 * 來(lái)訪(fǎng)問(wèn)該對(duì)象:
int a = 42;
int* p = &a;
cout<< *p<< endl; //由* 得到指針p指向的對(duì)象,即42
注意:解引用操作僅適用于那些確定指向了某個(gè)對(duì)象的有效指針
4.空指針空指針(null pointer) 不指向任何對(duì)象,在試圖使用一個(gè)指針之前可以先判斷它是否為空
int* p1 = nullptr;
int* p2 = 0; //直接將p2 初始化為字面常量0
int* p3 = NULL; //等價(jià)于 int *p3 = 0;
推薦使用 nullptr 初始化空指針
把 int 變量直接賦值給指針是錯(cuò)誤操作,即使這個(gè)int 變量的值恰好為0也不行
int zero = 0;
int* pi = zero; //錯(cuò)誤:不能把int 變量直接賦值給指針
建議初始化所有指針
5.賦值和指針指針和引用都能夠間接的訪(fǎng)問(wèn)其他對(duì)象,但是二者又有很大的不同,其中最重要的一點(diǎn)就是引用并不是一個(gè)對(duì)象。一旦定義了引用,就不能將其再綁定到另外的對(duì)象上。指針和它存放的地址之間就沒(méi)有這種限制了。
int a = 10;
int* p1 = 0;//p1初始化為空指針 不指向任何對(duì)象
int* p2 = &a;//p2 被初始化 指向 a
int* p3; //p3 沒(méi)有被初始化
p3 = p2; //現(xiàn)在 p2 和 p3 指向同一個(gè)對(duì)象 a
p2 = 0; //現(xiàn)在p2 不指向任何對(duì)象了
6.其他指針操作void* 是一種特殊的指針類(lèi)型,可用于存放任意對(duì)象的地址。一個(gè)void*指針存放一個(gè)地址,這一點(diǎn)和其他指針類(lèi)似。不同的是,我們不清楚這個(gè)指針指向什么類(lèi)型的對(duì)象。
double a = 3.14, * p = &a;
void* pv = &a; //a 可以是任意類(lèi)型的對(duì)象
pv = p; //pv 可以是任意類(lèi)型的指針
void指針的功能比較少,不能直接操作void指針?biāo)傅膶?duì)象,因?yàn)槲覀儾⒉恢浪@個(gè)對(duì)象是什么類(lèi)型。
概括說(shuō)來(lái),以void* 視角來(lái)看內(nèi)存空間也就只是內(nèi)存空間,沒(méi)辦法訪(fǎng)問(wèn)內(nèi)存空間中的所有對(duì)象。
3.理解復(fù)合類(lèi)型的聲明 1.定義多個(gè)變量經(jīng)常會(huì)有一種觀點(diǎn),在定義語(yǔ)句時(shí),類(lèi)型修飾符(* 或 &)作用于本次定義的全部變量
int* p1, p2; //p1 是指向int的指針,p2 是int
2.指向指針的指針指針也是內(nèi)存中的對(duì)象,也有自己的地址,因此允許把指針的地址放到另一個(gè)指針當(dāng)中,即允許另外一個(gè)指針指向指針。
int a = 10;
int* p = &a; //p 指向一個(gè) int 類(lèi)型的數(shù)
int** pp = &p; //pp 指向一個(gè) int 類(lèi)型的指針
//要訪(fǎng)問(wèn)最原始的那個(gè)對(duì)象,需要對(duì)指針的指針做兩次解引用
cout<< **pp<< endl; //a 的值
3.指向指針的引用引用本身不是一個(gè)對(duì)象,因此不能定義指向引用的指針。但指針是對(duì)象,所以存在對(duì)指針的引用
int a = 10;
int* p;
int*& r = p; // r 是一個(gè)對(duì)指針 p 的引用
r = &a; //r 引用了一個(gè)指針 因此給 r 賦值 &a ,就是讓指針 p 指向 a
*r = 0; //讓 p 指向的對(duì)象 也就是 a 的值變?yōu)?
四、const限定符有時(shí)我們希望第一這樣的一種變量,它的值不能夠被改變,可用const對(duì)變量的類(lèi)型加以限定。因?yàn)閏onst對(duì)象一旦創(chuàng)建后,其值就不能夠再修改,所以const對(duì)象必須初始化
const int a = get_size();// 運(yùn)行時(shí)初始化
const int b = 42;//編譯時(shí)初始化
const int c; //錯(cuò)誤:未初始化
1.初始化和const可以利用普通變量去初始化const變量
int a = 42;
const int b = a; //正確
int c = a; //正確
拷貝一個(gè)對(duì)象的值并不會(huì)改變它,一旦拷貝完成,新的對(duì)象就和原來(lái)的對(duì)象沒(méi)什么關(guān)系了。
2.默認(rèn)情況下,const對(duì)象僅在文件內(nèi)有效編譯器將在編譯過(guò)程中把用到該變量的地方都替換為對(duì)應(yīng)的值。
為了避免對(duì)同一個(gè)變量的重復(fù)定義。默認(rèn)情況下,const對(duì)象被設(shè)定為僅在文件內(nèi)有效。當(dāng)多個(gè)文件出現(xiàn)了同名的const變量時(shí),其實(shí)等同于在不同的文件中分別定義了獨(dú)立的變量。
如果想在多個(gè)文件之間共享const對(duì)象,必須在變量的定義之前添加extern。
1.const的引用可以把引用綁定到const對(duì)象上,即對(duì)常量的引用。與普通引用不同的是,對(duì)常量的引用不能修改它所綁定的值。
const int a = 1024;
const int& r = a; //正確
r = 20; //錯(cuò)誤:r是對(duì)常量的引用 不能改變
int& r2 = r; //錯(cuò)誤:試圖讓一個(gè)非常量引用 指向 一個(gè)常量對(duì)象
1.初始化和對(duì)常量的引用之前提到的 引用類(lèi)型 必須和其所引用的 對(duì)象類(lèi)型 一致,但是有兩種例外。其中一種就是在初始化常量引用時(shí)允許用任意表達(dá)式作為初始值,只要表達(dá)式的結(jié)果能轉(zhuǎn)換成引用的類(lèi)型即可。
int a = 10;
const int& r1 = a; //正確:允許將一個(gè)const int& 綁定到一個(gè)普通int對(duì)象上
const int& r2 = 42; //正確
const int& r3 = r1 * 2; //正確
int& r4 = r1 * 2; //錯(cuò)誤:r4 是一個(gè)普通的非常量引用
2.對(duì)const的引用,可能用一個(gè)非const的對(duì)象常量引用僅僅對(duì)可參與的操作做了限定,對(duì)于引用的對(duì)象本身是不是常量并未做限定。因?yàn)閷?duì)象也可能是一個(gè)變量,所以允許通過(guò)其他途徑改變它的值。
int a = 10;
const int& r1 = a; //正確:允許將一個(gè)const int& 綁定到一個(gè)普通int對(duì)象上
const int& r2 = 42; //正確
const int& r3 = r1 * 2; //正確
int& r4 = r1 * 2; //錯(cuò)誤:r4 是一個(gè)普通的非常量引用
2.指針和const與引用一樣,也可以讓指針指向常量或者變量。類(lèi)似于常量引用,指向常量的指針不能改變其指向的值。想要存放常量對(duì)象的地址,只能使用指向常量的指針。
const int a = 5; //a 是一個(gè)常量 它的值不能改變
int* ptr = &a; //錯(cuò)誤: ptr 是一個(gè)普通指針
const int* cptr = &a; //正確: cptr 可以指向一個(gè)整型常量
*cptr = 42; //錯(cuò)誤: 不能給 *cptr 賦值
之前提到過(guò),指針的類(lèi)型必須與所指向的對(duì)象類(lèi)型一致,其中一種例外是允許一個(gè)指向常量的指針指向變量。
int a = 10;
const int* cptr = &a; //正確:但是不能通過(guò) cptr 改變 a 的值
和常量引用一樣,指向常量的指針也沒(méi)有規(guī)定所指向的對(duì)象必須是常量。
1.const指針指針是對(duì)象而引用不是,因此可以把指針本身定義為常量。常量指針必須初始化,一旦初始化,它的指向就不能改變了。
int a = 10;
int* const p = &a; // 指針 p 就一直指向 a了,不能改變其指向了
指針本身是一個(gè)常量,也可以通過(guò)指針去修改其指向?qū)ο蟮闹?,只是指針的指向不能改變而?/p>3.頂層const
頂層const表示指針本身是一個(gè)常量,底層const表示指針?biāo)赶虻膶?duì)象是一個(gè)常量。
更一般的,頂層const可以表示任意對(duì)象是常量,這一點(diǎn)對(duì)任何數(shù)據(jù)類(lèi)型都適用。
底層const則與指針和引用等復(fù)合類(lèi)型有關(guān)。比較特殊的是:指針既可以是頂層const,也可以是底層const
int a = 0;
int* const p1 = &a; //不能改變 p1 的值,頂層const
const int ci = 42; //不能改變 ci 的值,頂層const
const int* p2 = &ci;// 允許改變 p2 的值 , 底層const
const int* const p3 = p2; //右邊時(shí)頂層const , 左邊的是底層const
const int& r = ci; //聲明引用的const 都是底層const
當(dāng)執(zhí)行對(duì)象拷貝操作時(shí),常量是頂層const 還是 底層const區(qū)別明顯。頂層const不受影響:
a = ci; //ci 是一個(gè)頂層const 對(duì)此操作無(wú)影響
p2 = p3; //p2 p3 指向的對(duì)象類(lèi)型相同,p3 頂層 const 的部分不受影響
執(zhí)行拷貝操作并不會(huì)改變對(duì)象的值,因此拷入拷出的對(duì)象是不是常量都沒(méi)什么影響
底層const的限制不能忽視。當(dāng)執(zhí)行拷貝操作時(shí),拷入拷出的對(duì)象必須具有相同的底層const,或者兩個(gè)對(duì)象的數(shù)據(jù)類(lèi)型能夠轉(zhuǎn)換。變量可以轉(zhuǎn)為常量,反之不行。
int* p = p3; //錯(cuò)誤: p3 有底層const p沒(méi)有
p2 = p3; //正確: p2 和 p3 都是底層 const
p2 = &a; //正確: int* 能轉(zhuǎn)換為 const int*
int& r = ci; //錯(cuò)誤:普通的int& 不能綁定到 int常量上
const int& r2 = a; //正確: const int& 可以綁定到一個(gè)普通int上
4.constexpr和常量表達(dá)式常量表達(dá)式是指值不會(huì)改變并且在編譯過(guò)程就能得到計(jì)算結(jié)果的表達(dá)式。顯然字面值屬于常量表達(dá)式,用常量表達(dá)式初始化的const對(duì)象也是常量表達(dá)式。
一個(gè)對(duì)象是不是常量表達(dá)式由它的數(shù)據(jù)類(lèi)型和初始值共同決定。
const int max_files = 20; //是
const int limit = max_files + 1; //是
int staff_size = 27; //不是常量表達(dá)式
const int sz = get_size(); //不是常量表達(dá)式 get_size 的具體值 需要到運(yùn)行時(shí)才能獲取到,所以不是
1.constexpr 變量C++ 11 標(biāo)準(zhǔn)規(guī)定,允許將變量聲明為constxepr類(lèi)型以便由編譯器來(lái)驗(yàn)證變量的值是否為一個(gè)常量表達(dá)式。聲明為constexpr的變量一定是一個(gè)常量,而且必須用常量表達(dá)式初始化
constexpr int mf = 20; //20 是常量表達(dá)式
constexpr int limit = mf + 1; // mf + 1 是常量表達(dá)式
const int sz = size(); // 只有當(dāng) size 是一個(gè) constxepr函數(shù)時(shí),才正確
一般來(lái)說(shuō),如果你認(rèn)定一個(gè)變量是常量表達(dá)式,那就把它聲明為constexpr類(lèi)型
2.字面值類(lèi)型常量表達(dá)式的值需要編譯時(shí)就得到計(jì)算,因此聲明constexpr時(shí) 用到的類(lèi)型必須有所限制。
算數(shù)類(lèi)型,引用和指針都屬于字面值類(lèi)型。
盡管指針和引用都能定義成constexpr,但是它們的初始值卻受到嚴(yán)格限制。一個(gè)constexpr指針的初始值必須為nullptr 或 0,或者是存儲(chǔ)與某個(gè)固定地址中的對(duì)象。
函數(shù)體內(nèi)部的變量一般來(lái)說(shuō)并非存放在固定地址中,定義于函數(shù)體之外的對(duì)象地址固定不變,能用來(lái)初始化constexpr指針。
3.指針和constexpr在constexpr聲明中,如果定義了一個(gè)指針,限定符constexpr僅對(duì)指針有效,與指針?biāo)赶虻膶?duì)象無(wú)關(guān)系。
const int* p = nullptr; //p 是一個(gè)指向整型常量的指針
constexpr int* q = nullptr; // q 是一個(gè)指向 整數(shù)的常量指針
constexpr把它所定義的對(duì)象置為了頂層const
五、處理類(lèi)型 1.類(lèi)型別名類(lèi)型別名(type alias) 是一個(gè)名字,他是某種類(lèi)型的同義詞。
有兩種方式可用于定義類(lèi)型別名。傳統(tǒng)的方式是使用關(guān)鍵字typedef
typedef double wages; //wages 是 double 的同義詞
typedef wages base, * p; //base 是 double 的同義詞,p 是 double* 的同義詞
C++ 11 標(biāo)準(zhǔn)規(guī)定了一種新的方法,使用別名聲明(alias declaration) 來(lái)定義類(lèi)型別名
using PII = pair; //PII 是 pair的同義詞
建議使用新標(biāo)準(zhǔn)的方法
1.指針、常量和類(lèi)型別名如果某一個(gè)類(lèi)型別名指代的是復(fù)合類(lèi)型或者常量,那么把他用到聲明語(yǔ)句中就會(huì)產(chǎn)生意外的結(jié)果。
typedef char* pstring;
const pstring cstr = 0; //cstr 是一個(gè)指向char 的常量指針
const pstring* ps; //ps 是一個(gè)指針 ,它的對(duì)象是指向char的 常量指針
2.auto 類(lèi)型說(shuō)明符C++ 11 標(biāo)準(zhǔn)引入了auto,auto能讓編譯器通過(guò)初始值來(lái)推算變量類(lèi)型。顯然,auto定義的變量必須有初始值。
int a = 10, b = 20;
auto c = a + b; //c 也是 int 類(lèi)型
1.復(fù)合類(lèi)型、常量和auto編譯器推斷出來(lái)的auto類(lèi)型有時(shí)候和初始值的類(lèi)型并不完全一樣,編譯器會(huì)適當(dāng)改變結(jié)果類(lèi)型使其更符合初始化規(guī)則。
使用引用其實(shí)是使用引用的對(duì)象,特別是當(dāng)引用被用作初始值時(shí),真正參與初始化的時(shí)引用對(duì)象的值。
int a = 20, & r = a;
auto b = r; // b = 20
auto 一般會(huì)忽略頂層const,保留底層const。
設(shè)置一個(gè)類(lèi)型為auto的引用時(shí),初始值中的頂層const常量屬性仍然保留。
3.decltype 類(lèi)型指示符有時(shí)候會(huì)遇到這種情況:希望通過(guò)表達(dá)式的類(lèi)型推斷出要定義的變量類(lèi)型,但是不想用該表達(dá)式的值初始化變量。為了滿(mǎn)足這一要求,C++ 11 標(biāo)準(zhǔn)引入了decltype,作用是選擇并返回操作數(shù)的數(shù)據(jù)類(lèi)型。編譯器會(huì)分析表達(dá)式得到它的類(lèi)型,卻不實(shí)際計(jì)算表達(dá)式的值。
decltype(fun()) sum = 10; // sum 的類(lèi)型就是 函數(shù)fun 的返回類(lèi)型(編譯器實(shí)際上并不會(huì)調(diào)用fun函數(shù))
與auto不同的是,如果decltype使用的是一個(gè)變量,則decltype返回改變量的類(lèi)型(包括頂層const和引用在內(nèi))
const int ci = 0, & cj = ci;
decltype(ci) x = 0; //x 的類(lèi)型是 const int
decltype(cj) y = x; //y 的類(lèi)型是 const int& ,y 綁定到變量 x
decltype(cj) z; //錯(cuò)誤: z是一個(gè)引用,必須初始化
1.decltype 和 引用如果decltype 使用的是一個(gè)表達(dá)式,則decltype 返回表達(dá)式結(jié)果對(duì)應(yīng)的類(lèi)型。
另一方面,如果表達(dá)式內(nèi)容是解引用操作,則decltpye會(huì)得到引用類(lèi)型。
int i = 42, * p = &i, & r = i;
decltype(r + 0) b; //r 是int&類(lèi)型 , r + 0 就是 int 類(lèi)型
decltype(*p) c; //錯(cuò)誤: c 是 int&類(lèi)型 , 需要初始化
如果變量名加上了一對(duì)括號(hào),則得到的類(lèi)型與不加括號(hào)時(shí)有所不同。如果給變量名加了一層或多層括號(hào),編譯器會(huì)把它當(dāng)成時(shí)一個(gè)表達(dá)式。
//decltype 的表達(dá)式如果是加上了括號(hào)的變量 結(jié)果將是引用
decltype((i)) d; //錯(cuò)誤: d 是 int& 類(lèi)型 , 需要初始化
decltype(i) e;
注意:decltpye((var)) 注意是雙層括號(hào),結(jié)果永遠(yuǎn)是引用。而decltype(var) 結(jié)果只有當(dāng)var本身是一個(gè)引用時(shí)才是引用。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁(yè)標(biāo)題:C++Primer讀書(shū)筆記——2.變量和基本類(lèi)型-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://chinadenli.net/article18/cdhogp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、網(wǎng)站排名、品牌網(wǎng)站制作、定制開(kāi)發(fā)、用戶(hù)體驗(yàn)、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容