C++學習(三) 複合數據類型(上)

提綱

  • 數組類型
  • 字符串類型
  • 結構體、共用體
  • 枚舉
  • 指針
  • 動態數組
  • 動態結構
  • 自動存儲、靜態存儲和動態存儲

一、數組類型
數組的聲明

  1. int yams[3];
  2. yams[0] = 7;
  3. yams[1] = 8;
  4. yams[2] = 6;
  5.  
  6. int yamcosts[3] = {20,30,5};

 

感覺不好的是,在C++中不能以int[] yam[3]這種方式聲明數組。
數組初始化的一些規則:
1.提供的值可以少於數組的長度
2.只有在定義數組時才能使用初始化。
像以這種方式聲明數組在C++中卻編譯不通過,在java中這樣寫完全是可以的。

  1. int hand[] ={1,2,3,4};
  2. int card[] = hand;

二、字符串
字符串是存儲在內存中連續字節的一系列字符。C++處理字符串有兩種方式,一是字符數組,這是來源於C的處理方式;二是C++中的string類型。
1.以字符數組方式聲明字符串

  1. char name1[] = {'s','u','n','y','y'};//不是字符串,長度爲5
  2. char name2[] = {'s','u','n','y','y','/0'};//是字符串,因爲有'/0'結尾,長度爲6
  3. char name3[] = "sunny";

看兩個簡單的小例子

 

  1. #include <iostream>
  2. #include <cstring>
  3. int main()
  4. {
  5.     using namespace std;
  6.     const int SIZE = 15;
  7.     char name1[SIZE];//空數組
  8.     char name2[SIZE] = "C++owboy";//初始化的數組
  9.     cout<<"Howdy!I'm "<<name2;
  10.     cout<<"!What's your name?/n";
  11.     cin>>name1;
  12.     cout<<"Well,"<<name1<<",your name has ";
  13.     cout<<strlen(name1)<<" letters and is stored/n";//要使用strlen()方法,需要使用cstring頭文件
  14.     cout<<"in an array of "<<sizeof(name1)<<" bytes./n";
  15.     cout<<"Your initial is "<<name1[0]<<"./n";
  16.     name2[3] = '/0';
  17.     cout<<"Here are the first 4 characters of my name:";
  18.     cout<<name2<<"/n";//這裏輸出C++,'/0'結束符作爲第四個字符。
  19.     return 0;
  20. }

 

 

  1. #include <iostream>
  2. int main()
  3. {
  4.     using namespace std;
  5.     const int SIZE = 20;
  6.     char name[SIZE];
  7.     char dessert[SIZE];
  8.     cout<<"Enter your name:/n";
  9.     cin>>name;//輸入Sunny Peng
  10.     cout<<"Enter your favorite dessert:/n";
  11.     cin>>dessert;
  12.     cout<<"I have some delicious "<<dessert;
  13.     cout<<" for you,"<<name<<"./n";
  14.     /*
  15.     我還未給dessert變量賦值,程序就已經輸出結果了。
  16.     第一個cin讀取的是Sunny,第二個cin讀取的是Peng
  17.     這是因爲cin以空白符來界定字符串的,它只能識別單個單詞,而不能識別語句。
  18.     */
  19.     return 0;
  20. }

 

第二個例子存在一點點小問題,但是C++提供了getline(),get()函數來解決這個問題。這兩個函數是用來讀取行的,在前一節中我知道cin是istream類的一個對象,那麼調用的方式就很簡單的,cin.get()或cin.getline(char arr[],int len)。

 

  1. /************************************************************************/
  2. /* cin.getline()例子                                                                                */
  3. /************************************************************************/
  4. #include <iostream>
  5. int main()
  6. {
  7.     using namespace std;
  8.     const int SIZE = 20;
  9.     char name[SIZE];
  10.     char dessert[SIZE];
  11.     cout<<"Enter your name:/n";
  12.     cin.getline(name, SIZE);//讀取行
  13.     cout<<"Enter your favorite dessert:/n";
  14.     cin.getline(dessert, SIZE);
  15.     cout<<"I have some delicious "<< dessert;
  16.     cout<<" for you,"<<name<<"./n";
  17.     return 0;
  18. }

 

 

  1. /************************************************************************/
  2. /* cin.get()例子                                                                                     */
  3. /************************************************************************/
  4. #include <iostream>
  5. int main()
  6. {
  7.     using namespace std;
  8.     const int SIZE = 20;
  9.     char name[SIZE];
  10.     char dessert[SIZE];
  11.     cout<<"Enter your name:/n";
  12.     //在讀取行時,帶參數的get函數並不丟棄換行符,但是不帶參數的get()函數能通過讀取一個字符來處理換行符。
  13.     //同時這裏也是函數重載的使用
  14.     cin.get(name, SIZE).get();
  15.     cout<<"Enter your favorite dessert:/n";
  16.     cin.get(dessert,SIZE).get();
  17.     cout<<"I have some delicious "<<dessert;
  18.     cout<<" for you,"<<name<<"./n";
  19.     return 0;
  20. }

 

2.string類
上面那種處理字符串的方式是C風格,用起來麻煩而且比較侷限。
C++提供了string類來處理字符串,在使用時也不必像上面那種比較麻煩的方式,string類提供了一些處理字符串的函數,用起來直觀而且方便。
string類在命名空間std中,使用string類,需要引入std::string命名空間。

 

  1. /************************************************************************/
  2. /* String例子                                                                     */
  3. /************************************************************************/
  4. #include <iostream>
  5. #include <string>
  6. #include <cstring>//C風格的字符串處理類
  7. int main()
  8. {
  9.     using namespace std;
  10.     char charr[20];
  11.     string str;
  12.     //在計算未初始化的字符數組長度時,空字符出現的位置是隨機的,可能strlen()計算的結果比數組本身長度還要大。
  13.     cout<<"Length of string in charr before input:"<<strlen(charr)<<endl;
  14.     cout<<"Length of string in str before input:"<<str.size()<<endl;
  15.     cout<<"Enter a line of text:/n";
  16.     cin.getline(charr,20);
  17.     cout<<"You entered:"<<charr<<endl;
  18.     cout<<"Enter another line of text:/n";
  19.     getline(cin,str);//把cin對象作爲參數,並且不需要爲輸入的字符串指定長度。
  20.     cout<<"Your entered:"<<str<<endl;
  21.     cout<<"Length of string in charr after input:"<<strlen(charr)<<endl;
  22.     cout<<"Length of string in str after input:"<<str.size()<<endl;
  23. }

 

三、結構體、共用體
1.結構體
一個結構體可以存儲多種類型的數據,結構體中的成員很像在類中聲明的字段,但是結構體沒有方法,結構體是一種比較靈活的數據格式。

  1. /************************************************************************/
  2. /* 結構體例子                                                                     */
  3. /************************************************************************/
  4. #include <iostream>
  5. //聲明結構體和聲明類差不多,使用的時候直接爲結構體賦值,而不需像類那樣來new
  6. //結構體可以聲明在函數內部或外部,就跟局部變量和全局變量一樣,只是作用域不同。
  7. //關鍵字struct只是表明inflatable是結構體,而數據類型爲inflatable;就好比聲明 class Test,Test是一種數據類型一樣
  8. struct inflatable
  9. {
  10.     char name[20];
  11.     float volume;
  12.     double price;
  13. };
  14. int main()
  15. {
  16.     using namespace std;
  17.     inflatable guest =
  18.     {
  19.         "Glorious Gloria",    //name
  20.         1.88,                        //volume
  21.         29.99                    //price
  22.     };
  23.     inflatable pal =
  24.     {
  25.         "Audacious Arthur",
  26.         3.12,
  27.         32.99
  28.     };
  29.     cout<<"Expand your guest list with "<<guest.name;
  30.     cout<<" and "<<pal.name<<"!/n";
  31.     cout<<"You can have both for $";
  32.     cout<<guest.price + pal.price <<"!/n";
  33.     return 0;
  34. }

試想想,如果一個函數需要不同類型的多返回值如何實現?在一般情況下,可以通過在類中聲明全局的字段來解決這個問題,但是這時候函數的返回類型爲void。在學習了結構體以後,我可以在適當的情況下通過結構體來處理函數多返回值的問題,結構體還真是一種比較輕便靈活的數據類型。

2.共用體
共用體類似於結構體,它也能夠存儲多種數據格式,但是共用體只能同時存儲一種數據類型。
例如聲明瞭如下的一個共用體,有3個成員變量,但是在使用時只能使用其中一個,在代碼段中,如果先後爲int_val,long_val,double_val成員賦值,那麼當前共用體中存儲的是double_val的值,其他成員的值爲0(因爲是數值類型,所以爲0)。共用體在內存中的空間爲最大成員所佔的空間。共用體有點多態的嫌疑,這個共用體既可以是int,也可以是long,還可以是double。共用體也是一種比較靈活的數據類型,在有些情況下可以使用它來做數據類型兼容。

  1. union one4all
  2. {
  3.     int int_val;
  4.     long long_val;
  5.     double double_val;
  6. };

四、枚舉
枚舉可以用於創建一組符號常量,使用起來也極其方便,用枚舉通過這些符號常量名我可以知道它所代表的含義。

  1. /************************************************************************/
  2. /* 枚舉例子                                                                     */
  3. /************************************************************************/
  4. #include <iostream>
  5. enum week
  6. {
  7.     Sunday,
  8.     Monday,
  9.     Tuesday,
  10.     Wednesday,
  11.     Thursday,
  12.     Friday,
  13.     Saturday
  14. };
  15. int main()
  16. {
  17.     using namespace std;
  18.     cout<<Sunday<<endl;
  19.     return 0;
  20. }

如果在聲明枚舉時爲枚舉中的每個常量賦了值,那麼在使用該枚舉時,只能使用這幾個值,超出這些值範圍的使用將是不合法的。

發佈了52 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章