1. 程式人生 > >【修煉C++】基礎知識點筆記-第2章

【修煉C++】基礎知識點筆記-第2章

重新學習c++的東西,此為《C++ Primer》讀書筆記,主要記錄零碎的知識。另外所有的C++11新標準也會被列出。

1,C++ 語言支援分離式編譯機制,該機制允許將程式分割為若干個檔案,每個檔案可以被獨立編譯。

2,名字的作用域:全域性作用域,塊作用域。

for(int val = 0;val<10;++val)

val 的作用域只在for語句內,因為其定義於for語句內。

3,: : 域訪問符

#include<iostream>

int reused = 42;

int main()
{
    int reused = 0;
    //使用區域性變數
    std::cout<<reused<<std::endl;
    //顯式訪問全域性變數
    std::cout<<::reused<<std::endl;
}

4, 引用;定義引用時,程式把引用和它的初始值繫結(bind)在一起。無法令引用重新繫結到另一個物件,因此引用必須初始化。引用本身並非一個物件,因此無法將指標指向一個引用

5,空指標;不指向任何物件,C++11中引入nullptr這種特殊型別的字面值。

6,指向指標的引用。

int i = 42;
int *p;      //p是一個int型指標
int *&r = p; //r是一個對指標p的引用

r = &i;      //r引用了一個指標,因此給r賦值&i就是令p指向i
*r = 0;      //解引用r得到i,也就是p指向的物件,將i的值改為0

7,const限定符;

      const物件一旦建立後其值就不能再改變,所以const物件必須初始化。(可以在執行時初始化,也可以在編譯時初始化)。

      編譯時初始化,編譯器將在編譯過程中把用到該變數的地方都替換成對應的值。

      預設情況下,const物件僅在檔案內有效。若要在檔案間共享,則需要在定義和宣告時都新增extern關鍵字,這樣定義一次即可

const int i = get_size(); //正確:執行時初始化
const int ci = 42;         //正確:編譯時初始化

//file_1.cc定義並初始化了一個常量,該常量能被其它檔案訪問
extern const int bufSize = fcn();
//file_1.h標頭檔案
extern const int bufSize;

8,const的引用

注意:常量引用僅對引用可參與的操作做出了限定,對於引用的物件本身是不是一個常量未做限定。因為物件也可能是個非常量,所以允許通過其他途徑改變它的值。

int i = 42;
int &r1 = i;        //引用ri繫結物件i
const int &r2 = i;  //r2也繫結物件i,但是不允許通過r2修改i的值
r1 = 0;             //r1並非常量,i的值修改為0
r2 = 0;             //錯誤:r2是個常量引用

9、指標和const

指向常量的指標:不能改變其所指向物件的值。const int  *ptr = &pi; 

常量指標:必須初始化,而且一旦初始化完成則它的值(也就是存放在指標中的那個地址)就不能再改變了。

                     int *const curr = &val

弄清楚這些宣告的含義最行之有效的辦法是從右向左閱讀。

10,頂層const

頂層const:表示任意的物件是個常量,對任何資料型別都適用。

底層const:與指標和引用的基本型別部分有關。

指標型別可以是頂層const也可以是底層const。

當執行物件的拷貝操作時,頂層const不受什麼影響。執行拷貝操作並不會改變被拷貝物件的值,因此,拷出和拷入的物件是否是常量都沒什麼影響。底層const的限制無法忽略,在執行物件的拷貝操作時,拷入和拷出的物件必須具有相同的底層const資格,或者兩個物件的資料型別必須能夠轉換。一般來說,非常量可以轉換為常量。

11,常量表達式:值不會改變並且在編譯過程就能得到計算結果的表示式。

       C++11新標準規定,允許將變數宣告為constexpr以便由編譯器來檢驗變數的值是否為一個常量表達式(若非則報錯)

       一個constexpr指標的初始值必須是nullptr或者0,或者是儲存於某個固定地址中的物件。在constexpr宣告中如果定義了一個指標,限定符constexpr僅對指標有效,與指標所指的物件無關。類似於頂層const。

12,類型別名:

        傳統方法:關鍵字typedef。例:typedef  wags double

        C++11新標準:關鍵字using。例:using wags=double

13,C++11新標準引進auto型別說明符,用它就能讓編譯器替我們去分析表示式所屬的型別。因為auto讓編譯器通過初始值來推算變數的型別,因此,auto定義的變數必須有初始值。注意在用auto在一條語句中宣告多個變數時,只能有一個基本資料型別,所以該語句中所有變數的初始基本資料型別都必須一樣。 

(1)使用引用其實是使用引用的物件,特別是當引用被用作初始值時,真正參與初始化的其實是引用物件的值,此時編譯器以引用物件的型別作為auto的型別,因此編譯器無法將auto變數指定為引用型別,需要程式設計師自行設定。

(2)auto一般會忽略掉頂層const,同時底層const會保留下來。

14,C++11新標準引入第二種型別說明符,decltype,它的作用是選擇並返回運算元的資料型別。

(1)引用從來都作為其所指物件的同義詞出現,只有在decltype處是個例外

(2)decltype的結果型別與表示式形式密切相關。如變數名加上一對括號,則編譯器就會把它當成是一個表示式。decltype((variable))的結果永遠是引用。賦值是會產生引用的一類 典型表示式,引用的型別就是左值的型別。

int ia[]={0,1,2,3,4,5,6,7,8,9}; //ia是一個含有10個整型的陣列
auto ia2(ia);                   //ia2是一個整型指標,指向ia的第一個元素
ia2=42;                         //錯誤:ia2是一個指標,不能用int值給指標賦值

//ia3是一個含有10個整數的陣列
decltype(ia) ia3 = {0,1,2,3,4,5,6,7,8,9}
ia3 = p; // 錯誤:不能用整型指標給陣列賦值
ia3[4] = i;//正確:把i的值賦給ia3的一個元素

15,C++11新標準規定,可以為資料成員提供一個類內初始值(in-class initializer)。建立物件時,類內初始值將用於初始化資料成員。沒有初始值的成員將被預設初始化。

struct Sales_data{
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
}