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
  2. #include
  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
  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 
  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 
  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 
  5. #include
  6. #include //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
  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
  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. }

如果在声明枚举时为枚举中的每个常量赋了值,那么在使用该枚举时,只能使用这几个值,超出这些值范围的使用将是不合法的。

你可能感兴趣的:(C++学习)