1. 程式人生 > >C++ primer plus--第四章:複合型別

C++ primer plus--第四章:複合型別

1.C++11陣列初始化方法

     使用大括號的初始化(列表初始化)作為一種通用初始化方式,新增功能如下:

            a.初始化陣列時可以省略等號(=):double earning[4] {1.2e4,1.6e4};

            b.可不在大括號內包含任何東西,將把所有元素都設定為0:

                   unsigned int counts[10] ={};

                  float balance[100] {};

            c.列表初始化禁止縮窄轉換:long plifs[]={25,92,3.0};

      C++標準模板庫(STL)提供了一種陣列替代品-------模板類vector ,而C++11新增了模板類array

2.字串

    C++允許拼接字串字面值,即將兩個用引號括起來的字串合併為1個。事實上任何兩個由空白(空格、製表符和換行符)分隔的字串常量都將自動拼接成一個。

     標準C語言庫函式(如:strlen():確定字串的長度)----------------由cstring提供

       sizeof運算子指出整個陣列的長度,strlen()函式返回的是儲存在陣列中的字串的長度,而不是陣列本身的長度,並且,strlen()只計算可見的字元,而不把空字元計算在內。

      cin是面向單詞的輸入,getline()函式讀取整行。它使用通過回車鍵輸入的換行符來確定輸入結尾。

        cin.getline();第一個引數是用來儲存輸入行的陣列的名稱,第二個引數是要讀取的字元數。getline()成員函式在讀取指定書目的字元或遇到換行符時停止讀取。

        cin.get()成員函式中接受的引數和解釋引數的方式都和getline()相同,但是get()並不再讀取並丟棄換行符,而是將其留在輸入佇列中。連續兩次使用get的話,第二次將發現不了任何可讀取的內容。需要藉助幫助跨過該換行符。使用不帶任何引數的cin.get()呼叫可讀取下一個字元(即使是換行符),因此可以用它來讀取換行符。

        getline()使用起來簡單一些,但get()使得檢查錯誤跟簡單些。如果輸入行包含的字元數比指定的多,則getline()和get()將把餘下的字元留在輸入佇列中,而getline()還會設定失效位,並關閉後面的輸入。

3.string類

        要使用string類必須在程式中包含標頭檔案string:cstring。

        string物件和字元陣列之間的主要區別是,可以將string物件宣告為簡單變數,而不是陣列。string類簡化了字串合併操作:運算子+----將兩個物件合併起來,運算子+=將字串附加到string物件的末尾。

       c語言庫中 strcpy()將字串複製到字元陣列中,strcat()將字串附加到字元陣列末尾。它們接受指出目標陣列最大允許長度的第三個引數。而string類具有自動調整大小的功能。

     int len1=str1.size();

     int len2=strlen(charr1);

      str1是一個物件,而size()是一個類方法。方法是一個函式,只能通過其所屬類的物件進行呼叫。

      cin和運算子<<還有cout和運算子>>可以用來將輸入儲存到string物件中,但如果讀取一行而不是一個單詞時,要用:getline(cin,str)這裡沒有使用句點表示法,因此這個getline()不是類方法,它將cin作為引數,指出到哪裡去查詢輸入。cin.getline(charr,20)這裡使用了句點表示法,這裡的getline()函式是istream類的一個類方法。

       除char型別外,C++還有型別wchar_t,C++11新增了char16_t和char32_t。C++分別使用字首L、u和U表示:

               wchar_t title[]=L"Chief Astrogator";//wchar_t string

              char16_t name[]=u"Felonia Ripova";//char16_t

              char32_t car[]= U"Humber Super Snipe";

  C++11還支援Unicode字元編碼方案UTF-8。根據編碼的數字值,字元可能儲存為1~4個八位組。C++使用字首u8來表示這種型別的字串字面值。

   C++11新增的另一種型別是原始(raw)字串。字元表示的就是自己:序列\n不表示換行符,表示兩個常規字元-----斜槓和n,原始字串將"(和)"用作定界符。使用字首R來標識原始字串:cout<<R"(Jim "King" Tutt uses "\n" instead of endl.)"<<'\n';

   上述程式碼顯示如下內容:Jim "King" Tutt uses \n instead of endl.

如果要顯示)":cout<<R"+*("(who would't?)",she whispered.)+*"<<endl;-------"(who would't?)",she whispered.

使用"+*(和)+*"替代了預設定界符"(和)"。

4.結構簡介

    結構是使用者定義的型別,而結構宣告定義了這種型別的資料屬性。定義了型別後,便可建立這種型別的變數。建立結構包括兩步,首先,定義結構描述----它描述並標記了能夠儲存在結構中的各種資料型別,然後按描述建立結構變數(結構資料物件)。 
       struct inflatable
    {    char name[20];
         float volume;
         double price;
    };

        關鍵字struct表明是一個結構的佈局,識別符號inflatable是這種主句格式的名稱,大括號中包含的是結構儲存的資料型別和列表,其中的每一項都是一條宣告語句。列表中的每一項都被稱為結構成員。

         定義結構後,便可建立這種型別的變數:inflatable hat;,C++允許在宣告結構變數時省略關鍵字struct;由於hat的型別為inflatable,因此可以使用成員運算子(.)來訪問各個成員。例如:hat.volume指的是volume成員。訪問類成員函式的方式就是從訪問結構成員變數的方式衍生而來。

          結構可以將string類作為成員。

         可以同時完成定義結構和建立結構變數的工作:

                    struct perks
                    {
                      int key_number;
                       char  car[12];
                    } mr_smith, ms_jones;甚至可以同時對其進行初始化。

5.公用體

  共用體是一種資料格式,它能儲存不同的資料型別,但只能同時儲存其中的一種型別。----結構體能同時儲存int、long和double,共用體只能儲存int、long或double。  
    如當資料項使用兩種或更多種格式時(但不會同時使用)時,可以節省空間:如商品目錄,有些ID為整數,有些為字串。

6.列舉

   C++的enum:建立符號常量,可以代替const。允許定義新型別,但要按嚴格的限制進行。

7.指標和自由儲存空間

      指標是一個變數,其儲存的是值的地址,而不是值本身。只需對變數應用取地址運算子(&),就可以獲得它的位置。指標名錶示的是地址,*運算子被稱為間接值或解除引用運算子。將其應用於指標,可以得到該地址處儲存的值。

      int updates = 6;
      int * p_updates;
      p_updates = &updates;

     int *ptr;//強調*ptr是一個int型別的值。
     int* ptr;//強調int*是一種型別----指向int的指標。
     int* p1,p2;//建立一個指標(p1)和一個int變數(p2):對於每一個指標變數名,都需要使用一個*。

     在C++中建立指標時,計算機將分配用來儲存地址的記憶體,但不會分配用來儲存指標所指向的資料的記憶體,一定要在對指標應用解除引用運算子(*)之前,將指標初始化為一個確定的、適當的地址。

       (1)C++中使用new來分配記憶體,C語言中使用malloc()來分配記憶體,C++中也可以使用。為一個數據物件獲得並指定分配記憶體的通用格式:typeName *pointer_name=new typeName;

        使用delete釋放記憶體,只能用delete來釋放使用new分配的記憶體。使用new來建立動態陣列。在編譯時給陣列分配記憶體被稱為靜態聯編,以為著陣列是在編譯時加入到程式的。但使用new時,如果在執行階段需要陣列,則建立它,如果不需要,則不建立。

       (2)使用new來建立動態結構:建立結構和訪問其成員。

            建立結構:同時使用結構型別和new。inflatable *ps=new inflatable;//建立一個未命名的inflatable型別,並將其地址賦給一個指標。箭頭運算子->可用於指向結構的指標。如果結構標誌符是結構名,則使用句點運算子;如果識別符號是指向結構的指標,則使用箭頭運算子。

另一種訪問結構成員的方法,如果ps是指向結構的指標,則*ps就是被指向的值-結構本身,可以用點運算子。

struct inflatable
    {
        char name[20];
        float volume;
        double price;
    };
    inflatable *ps=new inflatable;//建立了一個未命名的inflatable型別,並將其地址賦給一個指標
    訪問其成員:
        (1)ps->price//建立動態結構時,不能將成員運算子句點用於結構名,因為這種結構沒有名稱,只知道它的地址
        (2)(*ps).price//如果ps是指向結構的指標。*ps就是被指向的值——結構本身。C++的運算子優先規則要求括號。

      (3)模板類vector(C++98)

           vector<typeName> vt(n_elem);//名為vt的vector物件,可儲存n_elem個型別為typeName的元素,n_elem可以是整型常量,也可以是整型變數

      (4)模板類array(C++11)

           array<typeName,n_elem>arr;//建立名為arr的array物件,包含n_elem個型別為typename的元素,n_elem不能是變數。

      array物件和陣列儲存在相同的記憶體區域(即棧)中,而vector物件儲存在另一個區域(自由儲存區或堆中),可以將一個array物件賦給另一個array物件,而對於陣列,必須逐元素複製資料。