如果表達式里既有帶符號類型又有無符號類型,當帶符號類型取值為負時會出現異常結果。因為帶符號數會自動轉換成無符號數。
unsigned u=10;int i=-42;std::cout<<i+i<<std::endl;//輸出-84std::cout<<u+i<<std::endl;//如果int占32位,輸出4294967264引用與指針:
引用并非對象,引用只是為一個已經存在的對象所起的另外一個名字。
指針本身就是一個對象,允許對指針賦值和拷貝,而且在指針的生命周期內它可以先后指向不同的對象。
指針無需再定義時賦初值。但是在塊作用域定義內的指針一定要初始化。
利用相等操作符(==)或!=操作符比較指針時,比較的是兩個指針存放的地址值。
指向指針的引用:
引用本身不是一個對象,因此不能定義指向引用的指針。但指針是對象,所以存在對指針的引用。
int i=42;int *p=0;//p是一個int型指針int *&r=p;//r是一個對指針p的引用r=&i;//令p指向i*r=0;//令解引用r得到i,i=0;面對一條比較復雜的指針或引用的聲明語句時,從右到左閱讀有助于弄清楚它的真實含義。
const的引用:
常量引用僅對引用可參與的操作做出了限定,對引用的對象本身是不是一個常量未作限定。
const的指針:
指向常量的指針不能用于改變其所指對象的值。要想存放常量對象的地址,只能使用指向常量的指針。
const double pi=3.14;//pi是一個常量,值不能被改變double *ptr=π//錯誤,ptr是一個普通的指針const double *cptr=π//指向常量的指針指向一個常量對象*ptr=42;//錯誤,不能給*ptr賦值double dval=3.14;cptr=&dval;//正確,見note.Note: 指向常量的指針沒有規定其所指對象必須是一個常量。所謂指向常量的指針僅僅要求不能通過該指針改變對象的值,而沒有規定那個對象的值不能通過其他途徑改變。
const指針
常量指針表示指針本身是一個常量,其必須初始化,而且一旦初始化完成,則它的值,也就是存放在指針中的那個地址就不能再改變。表示為* const,不變的是指針本身的值,而非指向的那個值。
int errNumb=0;int *const currErr=&errNumb;//currErr一直指向errNumbconst double pi=3.14159;const double *const pip=π//pip是一個指向常量對象的常量指針*pip=2.172;//不能通過指針修改對象的值,因指向常量對象*curErr=0;//可以把curErr指針指向的對象重置,因其指向非常量對象。頂層const表示指針本身是一個常量。
底層const表示指針所指對象是一個常量。
int i=0;int *const p1=&i;//頂層constconst int ci=42;//頂層constconst int *p2=&ci;//底層const當執行對象的拷貝操作時,常量是頂層const還是底層const區別明顯。
頂層const不受什么影響。
i=ci;//正確p2=p3;//正確當執行對象的拷貝操作時,拷入和拷出對象必須具有相同的底層const資格,或者兩個對象的數據類型必須能夠轉換。
int *p=p3;//錯誤,p3包含底層const的定義,而p沒有p2=p3;//正確p2=&i;//正確,int*能轉化成const int*int &r=ci;//錯誤,普通的int&不能綁定到int常量上const int &r2=i;//正確:const int&可以綁定到普通的int上constexPR和常量表達式:
常量表達式是值不會改變并且在編譯過程就能得到計算結果的表達式。
我們允許將變量聲明為constexpr類型以便由編譯器來驗證變量的值是否是一個常量表達式。聲明為constexpr的變量一定是一個常量,而且必須用常量表達式初始化。
在constexpr聲明中如果定義一個指針,限定符constexpr僅對指針有效,與指針所指的對象無關。
const int *p=nullptr;//p是一個指向整型常量的指針constexpr int *q=nullptr;//q是一個指向整數的常量指針需要注意的是,const是給定類型的修飾。當使用類型別名的時候,類型別名就是一個類型。
typedef char *pstring;//pstring是char*const pstring cstr=0;//cstr是指向char的常量指針const pstring *ps;//ps是一個指針,它的對象是指向char的常量指針C++11新標準引入了auto類型說明符,用它就能讓編譯器替我們去分析表達式所屬的類型。
(1)推斷引用時,編譯器以引用對象的類型作為auto的類型。
(2)auto 一般會忽略掉頂層const,同時底層const則會保留下來。
(3)如果我們希望推斷出的auto類型是一個頂層const,需要顯式指出。
decltype類型指示符:選擇并返回操作數的數據類型。
decltype(f()) sum=x;//sum的類型就是函數f的返回類型。編譯器分析表達式并得到它的類型,卻不實際計算表達式的值如果decltype使用的表達式是一個變量,則decltype返回該變量的類型(包括頂層const和引用在內)。
const int ci=0,&cj=ci;decltype(ci) x=0;//x的類型是const intdecltype(cj) y=x;//y的類型是const int&,y綁定到變量xdecltype(cj) z;//錯誤,z是一個引用,必須初始化。如果decltype使用的表達式不是一個變量,則decltype返回表達式結果對應的類型。
int i=42,*p=&i,&r=i;decltype(r+0) b;//正確:加法的結果是int,因此b是一個(未初始化的)intdecltype(*p) c;//錯誤,c是int&,必須初始化。如果表達式的內容是解引用操作,則decltype將得到引用類型。decltype((variable)) (注意是雙層括號)的結果永遠是引用,而decltype(variable)結果只有當variable本身就是一個引用時才是引用。
decltype((i)) d;//錯誤:d是int &,必須初始化decltype(i) e;//正確:e是一個(未初始化的)int新聞熱點
疑難解答
圖片精選