第3章 字符串、向量和数组
内容
3.1 命名空间的using声明 74
3.2 标准库类型string 75
3.3 标准库类型vector 86
3.4 迭代器介绍 95
3.5 数组 101
3.6 多维数组 112
小结 117
术语表 117
除了第2章介绍的内置类型之外,C++(www.cppentry.com)语言还定义了一个内容丰富的抽象数据类型库。其中,string和vector是两种最重要的标准库类型,前者支持可变长字符串,后者则表示可变长的集合。还有一种标准库类型是迭代器,它是string和vector的配套类型,常被用于访问string中的字符或vector中的元素。
内置数组是一种更基础的类型,string和vector都是对它的某种抽象。本章将分别介绍数组以及标准库类型string和vector。
第2章介绍的内置类型是由C++(www.cppentry.com)语言直接定义的。这些类型,比如数字和字符,体现了大多数计算机硬件本身具备的能力。标准库定义了另外一组具有更高级性质的类型,它们尚未直接实现到计算机硬件中。
本章将介绍两种最重要的标准库类型:string和vector。string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列。本章还将介绍内置数组类型,和其他内置类型一样,数组的实现与硬件密切相关。因此相较于标准库类型string和vector,数组在灵活性上稍显不足。
在开始介绍标准库类型之前,先来学习一种访问库中名字的简单方法。
3.1 命名空间的using声明
目前为止,我们用到的库函数基本上都属于命名空间std,而程序也显式地将这一点标示了出来。例如,std::cin表示从标准输入中读取内容。此处使用作用域操作符(::)(参见1.2节,第8页)的含义是:编译器应从操作符左侧名字所示的作用域中寻找右侧那个名字。因此,std::cin的意思就是要使用命名空间std中的名字cin。
上面的方法显得比较烦琐,然而幸运的是,通过更简单的途径也能使用到命名空间中的成员。本节将学习其中一种最安全的方法,也就是使用using声明(using declaration),18.2.2节(第793页)会介绍另一种方法。
有了using声明就无须专门的前缀(形如命名空间::)也能使用所需的名字了。using声明具有如下的形式:
- using namespace::name;
一旦声明了上述语句,就可以直接访问命名空间中的名字:
- #include <iostream>
- // using声明,当我们使用名字cin时,从命名空间std中获取它
- using std::cin;
- int main()
- {
- int i;
- cin >> i; // 正确:cin和std::cin含义相同
- cout << i; // 错误:没有对应的using声明,必须使用完整的名字
- std::cout << i; // 正确:显式地从std中使用cout
- return 0;
- }
每个名字都需要独立的using声明
按照规定,每个using声明引入命名空间中的一个成员。例如,可以把要用到的标准库中的名字都以using声明的形式表示出来,重写1.2节(第6页)的程序如下:
- #include <iostream>
- // 通过下列using声明,我们可以使用标准库中的名字
- using std::cin;
- using std::cout; using std::endl;
- int main()
- {
- cout << "Enter two numbers:" << endl;
- int v1, v2;
- cin >> v1 >> v2;
- cout << "The sum of " << v1 << " and " << v2
- << " is " << v1 + v2 << endl;
- return 0;
- }
在上述程序中,一开始就有对cin、cout和endl的using声明,这意味着我们不用再添加std::形式的前缀就能直接使用它们。C++(www.cppentry.com)语言的形式比较自由,因此既可以一行只放一条using声明语句,也可以一行放上多条。不过要注意,用到的每个名字都必须有自己的声明语句,而且每句话都得以分号结束。
头文件不应包含using声明
位于头文件的代码(参见2.6.3节,第76页)一般来说不应该使用using声明。这是因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件里有某个using声明,那么每个使用了该头文件的文件就都会有这个声明。对于某些程序来说,由于不经意间包含了一些名字,反而可能产生始料未及的名字冲突。
一点注意事项
经本节所述,后面的所有例子将假设,但凡用到的标准库中的名字都已经使用using语句声明过了。例如,我们将在代码中直接使用cin,而不再使用std::cin。
为了让书中的代码尽量简洁,今后将不会再把所有using声明和#include指令一一标出。附录A中的表A.1(参见866页)列出了本书涉及的所有标准库中的名字及对应的头文件。
读者请注意:在编译及运行本书的示例前请为代码添加必要的#include指令和using声明。
3.1节练习
练习3.1:使用恰当的using声明重做1.4.1节(第13页)和2.6.2节(第76页)的练习。