第03章_字符床、向量和数组

命名空间的 using 声明

  • using namespace::name;
  • 头文件不应包含 using 声明

标准库类型 string

  • 默认初始化 string 会得到一个空的 string,该 string 对象中没有任何字符
    1
    std::string str; // str 中没有任何字符
  • 若提供一个字符串字面值,则该字面值中除了最后那个空字符外其他所有的字符都被拷贝到新创建的 string 对象中

定义和初始化 string 对象

string 对象上的操作

  • 当把 string 对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是 string

处理 string 对象中的字符

标准库类型 vector

  • 模板本身不是类或函数,相反可以将模板看作为编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化,当使用模板时,需要指出编译器应把类或函数实例化成何种类型

定义和初始化 vector 对象

1
2
3
4
std::vector<int> v1(10); // 10 个 0
std::vector<int> v2{10}; // 1 个 10
std::vector<int> v3(10, 1); // 10 个 1
std::vector<int> v4{10, 1}; // 10, 1

向 vector 对象中添加元素

其他 vector 操作

  • 相等性运算符和关系运算符依照字典顺序进行比较

迭代器介绍

  • 类似指针类型,迭代器也提供了对对象的间接访问
  • 迭代器有有效和无效之分。有效迭代器要么指向某个元素,要么指向容器中尾元素的下一位置;其余都是无效迭代器

使用迭代器

  • 若容器为空,begin 和 end 返回的是同一个迭代器
  • *iter: 返回元素的引用
  • iter->mem: 等价于 (*iter).mem
  • ++iter / –iter
  • iter1 == iter2 / iter1 != iter2
  • 试图解引用一个非法迭代器或尾后迭代器都是未被定义的行为
  • 如果 vector 中对象是常量,则只能使用 const_iterator;若不是,既能使用 iterator,又能使用 const_iterator
  • 凡是使用了迭代器的循环体,要注意不要轻易改变容器的大小,容易使得迭代器失效

迭代器运算

  • iter + n / iter - n
  • iter += n / iter -= n
  • iter1 - iter2: 测距离
  • = < <=: 比较位置

数组

  • 数组大小确定不变

定义和初始化内置数组

  • 编译时维度要已知

字符数组

1
2
3
4
char a1[] = {'C', '+', '+'}; // 无空字符
char a2[] = {'C', '+', '+', '\0'};
char a3[] = "C++"; // 自动添加空字符
const char a4[6] = "Daniel"; // error,没有空间放空字符

访问数组元素

指针和数组

  • 在大多数表达式中,使用数据类型的对象其实是使用一个指向该数组首元素的指针
    1
    2
    3
    int a[] = {1, 2};
    auto b(a); // b 是一个int*
    b = 42; // error
  • 使用 decltype 时上述转换不会发生,decltype(a) 返回的类型是由 2 个整数构成的数组

C 风格字符串

与旧代码的接口

  • c_str 函数的返回值是一个 C 风格的字符串,是一个指针,指向一个以空字符结束的字符数组,而这个数组所存的数据恰好与那个 string 对象的一样。结果指针的类型是 const char*,从而确保不会改变字符数组的内容
  • 无法保证 c_str 函数返回的数组一直有效,事实上,如果后续的操作改变了 string 的值就可能让之前返回的数组失去效用

多维数组

  • 多维数组其实是数组的数组