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对象,而对于数组,必须逐元素复制数据。

猜你喜欢

转载自blog.csdn.net/CHY1156957638/article/details/83819697