《C++ Primer 4th》读书摘要
最重要的标准库类型是 string 和 vector,它们分别定义了大小可变的字符串和集合。这些标准库类型是语言组成部分中更基本的那些数据类型(如数组和指针)的抽象。另一种标准库类型 bitset,提供了一种抽象方法来操作位的集合。
标准库string类型
有一种情况下,必须总是使用完全限定的标准库名字:在头文件中。理由是头文件的内容会被预处理器复制到程序中。
#include <string>
using std::string;
几种初始化string 对象的方式,因为历史原因以及为了与 C 语言兼容,字符串字面值与标准库 string 类型不是同一种类型。这一点很容易引起混乱,编程时一定要注意区分字符串字面值和 string 数据类型的使用,这很重要。
string s1; | 默认构造函数 s1 为空串 |
string s2(s1); | 将 s2 初始化为 s1 的一个副本 |
string s3("value"); | 将 s3 初始化为一个字符串字面值副本 |
string s4(n, 'c'); | 将 s4 初始化为字符 'c' 的 n 个副本 |
从标准输入读取 string 并将读入的串存储在 s 中。string 类型的输入操作符:
• 读取并忽略开头所有的空白字符(如空格,换行符,制表符)。
• 读取字符直至再次遇到空白字符,读取终止。
和输入操作符不一样的是,getline 并不忽略行开头的换行符。只要 getline 遇到换行符,即便它是输入的第一个字符,getline 也将停止读入并返回。如果第一个字符就是换行符,则 string 参数将被置为空 string。由于 getline 函数返回时丢弃换行符,换行符将不会存储在 string 对象中。
string 对象的操作
s.empty() | 如果 s 为空串,则返回 true,否则返回 false。 |
s.size() | 返回 s 中字符的个数 |
s[n] | 返回 s 中位置为 n 的字符,位置从 0 开始计数 |
s1 + s2 | 把 s1 和s2 连接成一个新字符串,返回新生成的字符串 |
s1 = s2 | 把 s1 内容替换为 s2 的副本 |
v1 == v2 | 比较 v1 与 v2 的内容,相等则返回 true,否则返 回 false |
!=, <, <=, >, and >= | 保持这些操作符惯有的含义 |
string 类类型和许多其他库类型都定义了一些配套类型(companion type)。通过这些配套类型,库类型的使用就能与机器无关(machine-independent)。任何存储 string 的 size 操作结果的变量必须为 string::size_type 类型。特别重要的是,不要把 size 的返回值赋给一个 int 变量。
大多数 string 库类型的赋值等操作的实现都会遇到一些效率上的问题,但值得注意的是,从概念上讲,赋值操作确实需要做一些工作。它必须先把 st1 占用的相关内存释放掉,然后再分配给 st2 足够存放 st2 副本的内存空间,最后把 st2 中的所有字符复制到新分配的内存空间。
当进行 string 对象和字符串字面值混合连接操作时,+ 操作符的左右操作数必须至少有一个是 string 类型的。
string 类型通过下标操作符([ ])来访问 string 对象中的单个字符。下标操作符需要取一个 size_type 类型的值,来标明要访问字符的位置。
对 string 对象中的单个字符进行处理。下表列出了各种字符操作函数,适用于 string 对象的字符(或其他任何 char 值)。这些函数都在 cctype 头文件中定义。可打印的字符是指那些可以表示的字符,空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种;标点符号则是除了数字、字母或(可打印的)空白字符(如空格)以外的其他可打印字符。
isalnum(c) | 如果 c 是字母或数字,则为 True。 |
isalpha(c) | 如果 c 是字母,则为 true。 |
iscntrl(c) | 如果 c 是控制字符,则为 true |
isdigit(c) | 如果 c 是数字,则为 true。 |
isgraph(c) | 如果 c 不是空格,但可打印,则为 true。 |
islower(c) | 如果 c 是小写字母,则为 true。 |
isprint(c) | 如果 c 是可打印的字符,则为 true。 |
ispunct(c) | 如果 c 是标点符号,则 true。 |
isspace(c) | 如果 c 是空白字符,则为 true。 |
isupper(c) | 如果 c 是大写字母,则 true。 |
isxdigit(c) | 如果是 c 十六进制数,则为 true。 |
tolower(c) | 如果 c 大写字母,返回其小写字母形式,否则直接返回 c。 |
toupper(c) | 如果 c 是小写字母,则返回其大写字母形式,否则直接返回 c。 |
C 标准库头文件命名形式为 name.h 而 C++ 版本则命名为 cname ,少了后缀,.h 而在头文件名前加了 c 表示这个头文件源自 C 标准库
标准库 vector 类型
vector 是同一种类型的对象的集合,vector称为容器。vector 不是一种数据类型,而只是一个类模板,可用来定义任
意多种数据类型。vector 类型的每一种都指定了其保存元素的类型。因此,vector<int> 和 vector<string> 都是数据类型。
vector<T> v1; | vector 保存类型为 T 对象。默认构造函数 v1 为空。 |
vector<T> v2(v1); | v2 是 v1 的一个副本。 |
vector<T> v3(n, i); | v3 包含 n 个值为 i 的元素。 |
vector<T> v4(n); | v4 含有值初始化的元素的 n 个副本 |
vector 对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。虽然可以对给定元素个数的 vector 对象预先分配内存,但更有效的方法是先初始化一个空 vector 对象,然后再动态地增加元素。
如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化(value initializationd)。这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何,取决于存储在 vector 中元素的数据类型。元素类型可能是没有定义任何构造函数的类类型。这种情况下,标准库仍产生一个带初始值的对象,这个对象的每个成员进行了值初始化。
vector 操作
v.empty() | 如果 v 为空,则返回 true,否则返回 false。 |
v.size() | 返回 v 中元素的个数。 使用 size_type 类型时,必须指出该类型是在哪里定义的。 vector 类型总是包括总是包括 vector 的元素类型:vector<int>::size_type |
v.empty() | 如果 v 为空,则返回 true,否则返回 false。 |
v.push_back(t) | 在 v 的末尾增加一个值为 t 的元素。 |
v[n] | 返回 v 中位置为 n 的元素。 |
v1 = v2 | 把 v1 的元素替换为 v2 中元素的副本。 |
v1 == v2 | 如果 v1 与 v2 相等,则返回 true。 |
!=, <, <=,>, and >= | 保持这些操作符惯有的含义。 |
C++ 程序员习惯于优先选用 != 而不是 < 来编写循环判断条件,选用或不用某种操作符并没有特别的取舍理由。学习完泛型编程后,你将会明白这种习惯的合理性。
reference:http://www.cnblogs.com/qlee/archive/2011/05/16/2048026.html
vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!
原因如下: reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。
两个函数的参数形式也有区别的,reserve函数之后一个参数,即需要预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小, 第二个参数是要加入容器中的新元素,如果这个参数被省略,那么就调用元素对象的默认构造函数。下面是这两个函数使用例子:
#include#include #include using namespace std;int vecTest1(){ vector myVect; myVect.reserve(100); for(int i=0;i<100;i++) { myVect.push_back(i); } myVect.resize(102); myVect[100]=1; myVect[101]=2; for(vector ::iterator iter=myVect.begin(); iter!=myVect.end();++iter) cout<<*iter<