第四章 复合类型

来源:互联网 发布:java 重载 为什么 编辑:程序博客网 时间:2024/05/16 05:18

第四章 复合类型
本章内容包括:
如何创建和使用数组。
如何创建和使用C-风格字符串。
如何创建和使用string类字符串。
如何使用getline()和get()方法来读取字符串。
如何混合输入字符串和数字。
如何创建和使用结构。
如何创建和使用共用体。
如何创建和使用枚举。
如何创建和使用指针。
如何通过new和delete来管理动态内存。
如何创建动态数组。
如何创建动态结构。
自动存储、静态存储和动态存储。

C++提供了复合类型,这种类型是基于整型和浮点类型创建的。影响最为深远的复合类型是类。它使我们正要学习的OOP堡垒。不过C++还支持几种更普通的复合类型,它们都来自C语言。例如数组可以存储多个同类型的值。一种特殊的数组可以存储字符串。结构可以存储多个不同类型的值。一种特殊的数组可以存储字符串(一系列的字符)。结构可以存储多个不同类型的值。而指针则是一种将数据所处位置告诉计算机的变量。本章将介绍所有这些复合类型(类除外),还将介绍new和delete及如何使用它们来管理数据。另外,还将简要地接受string类,它提供了另外一种处理字符串的途径。

4.1 数组
数组(array)是一种数据格式,能够存储多个同类型的值。每个值都存储在一个独立的数组元素中,计算机在内存中依次存储数组的各个元素。
要创建数组,可使用声明语句。数组声明应指出一下三点:
存储在每个元素中的值的类型、数组名、数组中的元素个数。

有效下标的重要性
编译器不会检查使用的下标是否有效。但程序运行后,这种赋值可能引发问题,它可能破坏数据或代码。也可能导致程序异常终止。所以必须确保程序只使用有效的下标值。

注意:当前的C++版本以及ANSI C都允许对函数中定义的常规数组进行初始化。不过,在一些使用C++翻译器(不是真正的编译)的老式实现中,C++翻译器将为不完全与ANSI C兼容的C编译创建C代码。

数组的初始化规则
C++有几条关于初始化数组的规则,它们限制了初始化的时刻。决定了数组中元素数目与初始化器中值的数目不相同时将发生的情况。
只有在定义数组时才能使用初始化,伺候就不能使用了,也不能将一个数组赋给另一个数组。

让编译器去做
通常,让编译器计算元素的个数是一种很糟的做法,因为其计数可能与您想象的不一样,不过,这种方法对于将字符数组初始化为一个字符串来说比较安全,很快读者将明白这一点。

C++标准模板库(STL)一种数组替代品----模板类vector,它比内置复合类型数组很复杂,也更灵活。

4.2 字符串
字符串是存储在内存的连续字节中的一系列字符。C++处理字符串的方式有两种。第一种来自C语言,常被称为C-风格字符串。本章将首先介绍它,然后介绍另一种基于string类库的方法。

C-风格字符串有一种特殊的性质:以空字符(null charcter)结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾。

记住:在确定存储字符所需存储字符串所需的最短数组时,别忘了将结尾的空字符串计算在内。
地址在C++中是一种独立的类型。

4.2.1 拼接字符串常量
  有时候,字符串很长,无法放到一行中。C++允许拼接字符串常量,即将两个引号括起的字符串合并为一个。事实上,任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。
注意:拼接时不会被链接的字符串字节添加空格,第二个字符串的第一个字符将紧跟在第一个字符串最后一个字符(不考虑\0)后面。第一个字符串中的\0后面。第一个字符串中的\0字符将被第二个字符串的第一个字符取代。

4.2.2 在数组中使用字符串
要将字符串存储到数组中,最常用的方法有两种——将数组初始化为字符串常量、将键盘或文件输入读入的数组中。
注意:如果系统没有提供cstring头文件,请使用老版本string.h

4.2.3 字符输入
cin是如何确定已完成字符串输入呢?由于不能通过键盘输入空字符,因此cin需要用别的方法来确定字符串的结束位置。cin使用空白来定字符串的界。这意味着cin在获取字符数组输入时只读取一个单词。读取单词后,cin将该字符串放到数组中,并字符结尾添加空字符。
另一个问题是,输入字符串可能比目标数组长,像这个例子一样使用cin,确实不能防止将包含30字符的字符串放到20个字符的数组中的情况发生。
很多程序都依赖字符串输入,因此有必要对这一主题做进一步探讨。我们必须使用cin较高级的特性,这将在17章介绍。

4.2.4 每次读取一行字符串输入
istream中的类提供了一些面向行的类成员函数:getline和get。这两个函数都读取一行输入。直到达换行符。然而getline对其换行符,而get则相反。

注意:有些早期的C++版本没有实现当前C++ I/O程序包的全部功能。具体地说,getline成员函数并不是总可用的。
注意:有些C++的老版本没有实现不接受任何参数的get变体,但实现了接受一个char参数的get()变体。

需要指出的一点是,C++允许函数有多个版本,条件是这些版本的参数列表不同,如果使用的是cin.get(name,ArSize),则编译器知道是要将一个字符串放入数组中。因而将使用适当的成员函数。如果使用的是cin.get(),则编译器知道是要读取一个字符。第8章将探索这种特性——函数重载。

4.2.5 混合输入字符串和数字
C++程序长使用指针(而不是数组)来处理字符串。我们将在介绍指针后,再介绍字符串方面的特性。
下面介绍一种较新的处理字符的方式:C++string类。

4.3 string类简介
ISO/ANSI C++标准通过它添加string类扩展了C++库,因此现在可以string类型的变量(使用C++的话说是对象)而不是字符数组来存储字符串。
读者将看到,string类使用起来比数组简单,同时提供了将字符串作为一种数据类型的表示方法。
要使用string类,必须在程序中包含头五年级string。string类位于名称空间std中,因此您必须提供一条using编译指令,或者使用std::string来引用它。string类定义隐藏了字符串的数组性质,让您能够像处理普通变量那样处理字符串。

从这个范例可知,在很多方面,使用string对象的方式与使用字符数组相同:
可以使用C-风格字符串来初始化string对象。
可以使用cin来将键盘输入存储到string对象中。
可以使用cout来显示string对象
可以使用数组方法来访问存储在string对象中的字符。

4.3.1 赋值、拼接和附加
使用string类时,某些操作比使用数组时更简单。例如不能将一个数组赋给另一个数组,但可以将一个string对象赋给另一个string对象。
可以将C语言式的字符串或string对象与string对象相加,或将它们附加到string对象的末尾。

4.3.2 string 类的其他操作
在C++新增string类之前,程序员也需要完成诸如给字符串赋值等工作。对于C语言式的字符串,程序员使用C语言库中的函数来完成这些任务。头文件cstring(以前为string.h)提供了这些函数。
另外,使用字符数组时,总是存在目标数组过小,无法存储指定信息的危险.

函数strcat实体将全部12个字符赋值到数组site(10字节)中。这将覆盖相邻的内存,这可能导致程序终止,或者程序继续运行,但数据损坏,string类具有自动调整大小的功能,从而能避免这种问题发生。C函数库确实提供了与strcat和strcpy类似的函数strncat和strncpy,它们接受指出目标数组最大允许长度的第三个参数,因此更为安全,但使用它们进增加了编写程序的复杂度。
函数strlen是一个常规函数,它接受一个C-风格字符串作为参数,并返回该字符串包含的字符数。函数size的功能基本上与此相同,但语法不同:str1不是被用作函数参数,而是位于函数名之前。它们之间用句点连接。

4.3.3 string类 I/O
正如读者知道的可以使用cin和操作符>>来将输入存储到string对象中,使用cout和操作符<<来显示string对象。其语法与处理C-风格字符串相同。但每次读取一行而不是一个单词时,使用的语法不同。

0 0
原创粉丝点击