2.4.4 constexpr和常量表示式
常量表示式是指值不會改變並且在編譯過程就能得到計算結果的表示式,字面值屬於常量表示式,用常量表示式初始化的const物件也是常量表示式
乙個物件是不是常量表示式是由它的資料型別和初始值決定的
const
int max_files=20;//max_files是常量表示式
const
int limit=max_files+1;//limit是常量表示式
int staff_size=27;//staff_size不是常量
const
int sz=get_size();//sz不是常量表示式
sz本身是乙個常量,但它的具體值直到執行時才能獲得,所以也不是常量表示式。
constexper變數
允許將變數宣告constexpr型別以便由編譯器驗證變數的值是否是乙個常量表示式。宣告constexpr的變數一定是乙個常量,而且必須用常量表示式來初始化:
constexpr int mf =20;
constexpr int limit=mf+1;
指標和constexpr
必須明確一點,在constexpr宣告中如果定義了乙個指標,限定符constexpr僅對指標有效,與指標所指的物件無關
const int *p=nullptr//p是乙個指向整型常量的指標
constexpr int *q=nullptr//q是乙個指向整數的常量指標
p和q型別相差甚遠,p是乙個指向常量的指標,而q是乙個常數指標,其中的關鍵在constexpr把它定義為了頂層const
與其它常量指標類似,constexpr指標既可以指向常量也可以指乙個非常量
constexpr
int *np=nullptr;//np是乙個指向整數的常量指標,值為空
int j=0;
constexpr
int i=42;
//i和j都是定義在函式體之外
constexpr
const
int *p=&i;//p是常量指標,指向整型常量i
constexpr
int *p1=&j;//p1是常量指標,指向整數
2.5型別別名
型別別名是乙個名字,是某種型別的同義詞
兩種方法可用於定義型別別名。
typedef double wages;//wages是double的同義詞
typedef wages base,p;//base是double的同義詞,p是double的同義詞
使用別名宣告來定義型別的別名:
using si=sales_item//si是sales_items的同義詞
型別別名和型別的名字等價,只要是型別的名字能出現的地方,就能使用型別別名:
wages hourly,weekly;
si item;//等價於sales_item item
指標,常量和型別別名
如果某個型別別名指代的是復合型別或常量,那麼吧它用到宣告語句裡就會就產生意想不到的後果。例如下面的宣告語句用到了型別pstring,它實際是型別char*的別名
typedef char *pstring;
const pstring cstr=0;//cstr是指向char的常量指標
const pstring *ps;//ps是乙個指標,它的物件是指向char的常量指標
此段學得不好,見書本
2.5.2auto型別說明符
c+11心標準引入auto型別說明符auto讓編譯器通過初始值來推算變數的型別。顯然auto定義的變數必須有初始值:
auto item=val1+val2;item初始化為vall和val2相加的結果
使用auto也能在一條語句中宣告多個變數,因為一條宣告語句只能有乙個基本資料型別,
使用auto也能在一條語句中宣告多個變數。因為一條宣告語句中只能有乙個基本資料型別,所以該語句中所有變數的初始基本資料型別都必須一樣:
auto i=0,*p=&i;//正確:i是整數,p是整型指標
auto sz=0,pi=3.14
//錯誤:sz和pi的型別不一致
復合型別,常量和auto
編譯器推斷出來的auto型別有時候和初始值的型別並不完全一樣,編譯器會適當地改變結果型別使其更符合初始化規則。
使用引用其實是使用引用的物件,特別是當引用被用作初始值時,真正參與初始化的其實是引用物件的值。此時編譯器以引用物件的型別作為auto的型別:
int i=0,&r=i;
auto a=r;//a是乙個整數
其次,auto一般還會忽略頂層const,同時底層則會保留下來,比如當初始值指向常量的指標:
const
int ci=i,&cr=ci;
auto b=ci;//b是乙個整數(ci)
auto c=cr;/c是乙個整數(cr是ci的別名,ci本身是乙個頂層const)
auto d=&i;//d是乙個整型指標(整數的位址就是指向整數的指標)
auto e=&ci;//e是乙個指向整數常量的指標(對常量物件取位址是一種底層const)
如果希望推斷出的auto型別是乙個頂層const,需要明確指出:
const
auto f=ci;
還可以將引用的型別設為auto,此時原來的初始化規則仍然適用:
auto &g=ci;//g是乙個整型常量引用,繫結到ci
auto &h=42;//錯誤:不能為非常量引用繫結字面值
const
auto &j=42;//正確:可以為常量引用繫結字面值
設定乙個型別為auto的引用時,初始值中頂層常量屬性任然保留。和往常一樣,如果我們給初始值繫結引用和往常一樣,如果我們給初始值繫結乙個引用,則引用的常量就不是頂層常量了
當在一條語句中定義多個變數,切記,符號&和*只屬於某個宣告符,而非基本資料型別的一部分,因此初始值必須是同乙個型別:
auto k=ci,&l=i;//k是整數,l是整數型別
auto &m=此,*p=&ci;//m是對整數常量的引用,p是指向整型常量的指標
auto &n=i,*p2=&ci;
2.5.3
decltype型別指示符
希望從表示式的型別推斷出要定義的變數的型別,但是不想用該表示式,這個符號的作用是decltype,它的作用是選擇並返回運算元的資料型別,在此過程中,編譯器分析表示式並得到它的型別,卻不實際計算表示式的值:
decltype(f())sum=x;//sum的淚洗就是符號f的返回型別
編譯器並不實際呼叫函式f,而是使用當呼叫發生時f的返回值,編譯器為sum指定的型別是什麼呢?,就是假如f被呼叫的話將返回的那個型別。
decltype處理頂層const和引用的方式和auto有些不同,如果decltype使用的表示式是乙個變數,則decltype返回該變數的型別
const
C Primer讀書筆記(八)
stl容器之關聯容器 集和多集 set 和multiset 容器類 乙個集合 include 是乙個容器,它其中所包含的元素的值是唯一的。這在收集乙個資料的具體值的時候是有用 的。集合中的元素按一定的順序排列,並被作為集合中的例項。如果你需要乙個鍵 值對 pair 來儲存資料,map 也是乙個 關聯...
C primer 讀書筆記
第2 章 變數和基本型別 1 變數直接初始化和變數 複製初始化 int ival 1024 direct initialization int ival 1024 copy initialization 初始化不是賦值 2 內建型別復 制初始化和直接初始化幾乎沒有區別 但 對類型別物件來 說,有些初...
C Primer讀書筆記
前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...