《C++ Primer》 第3章 字符串、向量和数组

3.1 命名空间的 using 声明

域操作符(::)的含义是:编译器应从操作符左侧名字所示作用域中寻找右侧那个名字。因此,std::cin 的意思就是要使用命名空间 std 中的名字 cin。而使用 using 声明后则无需专门的前缀也能使用所需的名字了。

1
2
3
using std::cin;
int i;
cin >> i;

更方便的方法:

1
using namespace std;

这样就可以使用 std 命名空间中所有的名字了。

3.2 标准库类型 string

​ 标准库类型 string 表示可变长的字符序列,使用 string 类型必须首先包含 string 头文件。

1
2
#include <string> // 包含 string 头文件
using std::string; // string 定义在命名空间 std 中

3.2.1 定义和初始化 string 对象

​ 如何初始化类的对象是由类本身决定的。如下是初始化 string 对象的常用方式:

1
2
3
string s1(s2);
string s1 = s2; // 同上
string s1(n, 'c') // 将s1初始化为由连续n个'c'组成的字符串

3.2.2 string 对象上的操作

1
2
3
4
5
6
7
8
os << s; // output stream
is >> s; // 输入到s,字符串以空白分隔
getline(is, s); // 从is中读取一行到s
s.empty();
s.size();
s[n];
s1 + s2;
<, <=, >, >= // 利用字符在字典中的顺序进行比较,大小写敏感

读写 string 对象

1
2
cin >> s; // 将 string 对象读入 s,遇到空白停止
cin >> s1 >> s2; // 把第一个输入到s1中,第二个输入到s2中

3.2.3 处理 string 对象中的字符

cctype头文件中定义了一组标准库函数来处理 string 对象中的字符。比如判断字符是否为数字、字母、控制字符、可打印字符、大写、小写、标点等,以及大小写转换。(p82)

基于范围的 for 语句

1
2
3
4
5
for (declaration: expression)  // 跟python中 for declaration in expresson 类似
statement
// 举例
for (auto c : str)
cout << c << endl;

使用范围 for 语句改变字符串中的字符

1
2
for (auto &c : str)  // c是一个引用,故赋值语句将改变s中字符的值
c = toupper(c);

3.3 标准库类型 vector

​ 标准库类型 vector 表示对象的集合,其中所有对象的类型都相同。集合中每个对象都有一个与之对应的索引,索引用于访问对象。因为 vectot 容纳着其他对象,所以它也常被称作容器

​ 使用 vector:

1
2
3
4
5
6
# include <vector>
using std::vector

vector<int> ivec; // 定义一个能容纳int类型集合的对象
vector<Sales_item> Sales_vec;
vector<vector<string>> file;

vector 能容纳绝大多数类型的对象作为其元素。

3.3.1 定义和初始化 vector 对象

1
2
3
4
5
6
7
vector<T> v1;
vector<T> v2(v1);
vector<T> v3 = v1;
vector<T> v4(n, val);
vector<T> v5(n);
vector<T> v6{a,b,c...};
vector<T> v7 = {a,b,c...};

3.3.2 向 vector 对象中添加元素

​ vector 的成员函数 push_back() 能将一个元素添加到 vector 的尾端。

3.3.3 其他 vector 操作

​ 跟 string 差不多。

3.4 迭代器介绍

迭代器能用于访问 string 对象和 vector 对象的元素,并且所有的标准库容器都能使用迭代器。使用迭代器能访问某个元素,迭代器也能从一个元素移动到另外一个元素。

3.4.1 使用迭代器

​ 能使用迭代器的类型都拥有能返回迭代器的成员函数,比如 beginend。其中 begin 成员负责指向第一个元素,end 成员则负责指向容器(或 string 对象)的”尾元素的下一个位置“的迭代器。end 成员返回的迭代器常被称为尾后迭代器。如果容器为空,则 begin 和 end 返回的是同一个元素。

迭代器运算符

  • *iter 返回迭代器iter所指元素的引用
  • iter->men 相当于(*iter).men
  • ++iter 令 iter 指向容器下一个元素,同理有 —iter,iter + n,iter1 - iter2 等
  • iter1 > iter2 比较位置关系,靠后的值大

迭代器类型

拥有迭代器迭代器的标准库类型使用 iterator 和 const_iterator 来表示迭代器的类型。const_iterator 和常量指针差不多,能读但不能修改所指元素的值,而 iterator 所指的对象可读可写。 如果容器对象是一个常量,则只能使用 const_iterator;否则两种类型都能使用。

容器操作使迭代器失效

​ 谨记,但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。

3.5 数组

数组 是一种类似标准库类型 vector 的数据结构,与 vector 不同的是数组大小固定,不能随意向数组中增加元素。

3.5.1 定义和初始化内置数组

显式初始化数组元素

​ 如果声明时没有指明维度,编译器会根据初始值的数量计算并推断出来;如果指明了维度,那么初始值的总数量不应该超出指定的大小。

字符数组的特殊性

​ 当使用字符串字面值初始化字符数组时,一定要注意字符串字面值的结尾处还有一个隐藏的空字符,这个空字符也会像字符串的其它字符一样被拷贝到数组里去。

1
2
3
char a1[3] = {'c', 'p', 'p'};  // 正确
char a2[4] = "cpp"; // 正确
char a3[3] = "cpp"; // 错误

理解复杂的数组声明

1
2
3
4
int *ptrs[10];                  // ptrs是含有10个整型指针的数组
int &refs[10] = /*?*/; // 错误:不存在引用的数组
int (*Parray)[10]; // Parray指向一个整型数组
int (&arrRef)[10]; // arrRef引用一个整型数组

3.5.3 指针和数组

​ 数组类型的对象其实是一个指向该数组首元素的指针。该指针也是一个迭代器。

-------------本文结束感谢您的阅读-------------