1.string暂时没有发现什么特别需要记的。C++中string封装的很好,支持各种cin,cout,+,-,=,...运算符。
总的来说,相对于 C++ 内 置数据类型的数组和指针而言,程序员应优先使用标准库类类型。
在出现标准库之前,C++ 程序大量使用数组保存一组对象。而现代的 C++ 程 序则更多地使用 vector 来取代数组,数组被严格限制于程序内部使用,只有当 性能测试表明使用 vector 无法达到必要的速度要求时,才使用数组。
与 vector 类型相比,数组的显著缺陷在于:数组的长度是固定的,而且程 序员无法知道一个给定数组的长度。数组没有获取其容量大小的 size 操作,也 不提供 push_back 操作在其中自动添加元素。如果需要更改数组的长度,程序 员只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组空间中 去。
与使用标准 vector 类型的程序相比,依赖于内置数组的程序 更容易出错而且难于调试。
1.1使用string时,先引入头文件
#include <string>
using std::string;
1.2几种初始化string对象的方式
string s1; |
默认构造函数 s1 为空串 |
string s2(s1);
|
将 s2 初始化为 s1 的一个副本 |
string s3("value");
|
将 s3 初始化为一个字符串字面值副本 |
string s4(n, 'c');
|
将 s4 初始化为字符 'c' 的 n 个副本 |
另外string类型和C中的字符数组是不同的,这点和NSString一样。
1.3 string::size_type 类型
从逻辑上来讲,size() 成员函数似乎应该返回整形数值,或无符号整数。但事实上,size 操作返回的
是 string::size_type 类型的值 。
虽然我们不知道 string::size_type 的确切类型,但可以知道它
是 unsigned 型。对于任意一种给定的数据类型,它的 unsigned 型
所能表示的最大正数值比对应的 signed 型要大倍。这个事实表
明 size_type 存储的 string 长度是 int 所能存储的两倍。
为了避免溢出, 保存一个 stirng 对象 size 的最安全的方法就是使用标准库类
型 string::size_type。
2.vector:
2.1 vector 是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。 和 string 对象一样,标准库将负责管理与存储元素相关的内存。我们把 vector 称为容器,是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种 类型的。 从定义上看,很像NSArray。
2.2 使用 vector 之前,必须包含相应的头文件
#include <vector>
using std::vector;
2.3 vector 是一个类模板(class template)。使用模板可以编写一个类定义 或函数定义,而用于多个不同的数据类型。因此,我们可以定义保存 string 对 象的 vector,或保存 int 值的 vector,又或是保存自定义的类类型对象(如 Sales_items 对象)的 vector。
声明从类模板产生的某种类型的对象,需要提供附加信息,信息的种类取决 于模板。以 vector 为例,必须说明 vector 保存何种对象的类型,通过将类型 放在类型放在类模板名称后面的尖括号中来指定类型:
vector<int> ivec; // ivec holds objects of type int
vector<Sales_item> Sales_vec; // holds Sales_items
如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行
值初始化(value initializationd)。这个由库生成的初始值将用来初始化容 器中的每个元素,具体值为何,取决于存储在 vector 中元素的数据类型。
vector<string> fvec(10); // 10 elements, each initialized to 0
vector<string> svec(10); // 10 elements, each an empty string
2.4 关键概念:vector 对象动态增长
vector 对象(以及其他标准库容器对象)的重要属性就在于可以在运行 时高效地添加元素。因为 vector 增长的效率高,在元素值已知的情况 下,最好是动态地添加元素。
正如第四章将介绍的,这种增长方式不同于 C 语言中的内置数据类型, 也不同于大多数其他编程语言的数据类型。具体而言,如果读者习惯了 C 或 Java 的风格,由于 vector 元素连续存储,可能希望最好是预先分 配合适的空间。但事实上,为了达到连续性,C++ 的做法恰好相反,具 体原因将在第九章探讨。
虽然可以对给定元素个数的 vector 对象预先分配内 存,但更有效的方法是先初始化一个空 vector 对象, 然后再动态地增加元素(我们随后将学习如何进行这样 的操作)。
2.5 vector 对象的操作
v.empty()
v.size()
v.push_back(t);//在 v 的末尾增加一个值为 t 的元素。
v[n] ;返回 v 中位置为 n 的元素。
v1 = v2 ;把 v1 的元素替换为 v2 中元素的副本。
v1 == v2 ;如果 v1 与 v2 相等,则返回 true。
!=, <, <=,
>, and >= ;保持这些操作符惯有的含义。
2.6 vector 对象的 size
empty 和 size 操作类似于 string 的相关操作(3.2.3 节)。成员函数
size 返回相应 vector 类定义的 size_type 的值。
使用 size_type 类型时,必须指出该类型是在哪里定义的。 vector 类型总是包括总是包括 vector 的元素类型:
vector<int>::size_type // ok
vector::size_type // error
2.7 向 vector 添加元素
push_back 操作接受一个元素值,并将它作为一个新的元素添加到 vector
对象的后面,也就是“插入(push)”到 vector 对象的“后面(back)
string word;
vector<string> text; // empty vector
while (cin >> word) {
text.push_back(word); // append word to text
}
2.8 vector可以进行下标操作,但是不能利用下标操作添加元素(只能用push_back());
2.9 通常,函数不应该有 vector 或其他标准库容器类型的 形参。调用含有普通的非引用 vector 形参的函数将会 复制 vector 的每一个元素。
从避免复制 vector 的角度出发,应考虑将形参声明为引用类型。然而,看 过第十一章后我们会知道,事实上,C++ 程序员倾向于通过传递指向
容器中需要 处理的元素的迭代器来传递容器:
// pass iterators to the first and one past the last element to print
void print(vector<int>::const_iterator beg, vector<int>::const_iterator end)
{
while (beg != end) {
cout << *beg++;
if (beg != end) cout << " "; // no space after last element
}
cout << endl;
}