[C++]C++Primer Chapter 3
字符串、向量和数组
3.1 命名空间的using声明
3.2 标准库类型string
3.2.1 定义和初始化string对象
直接初始化和拷贝初始化
3.2.2 string对象上的操作
读写string对象
从流读:在执行读取操作时,string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。
getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了),然后把所读的内容存入到那个string对象中去(注意不存换行符)。
getline也会返回它的流参数。因此既然输入运算符能作为判断的条件(参见1.4.3节,第13页),我们也能用getline的结果作为条件。
string::size_type类型
它是一个无符号类型的值(参见2.1.1节,第30页)而且能足够存放下任何string对象的大小。所有用于存放string类的size函数返回值的变量,都应该是string::size_type类型的。
比较string对象
1.如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应位置上的字符相同,就说较短string对象小于较长string对象。
2.如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
3.2.3 处理string对象中的字符
3.3 标准库类型vector
3.3.1 定义和初始化vector对象
3.3.2 向vector对象中添加元素
范围for语句体内不应改变其所遍历序列的大小。
3.3.3 其他vector操作
3.4 迭代器介绍
3.4.1 使用迭代器
begin和end运算符
begin和end返回的具体类型由对象是否是常量决定,如果对象是常量,begin和end返回const_iterator;如果对象不是常量,返回iterator
为了便于专门得到const_iterator类型的返回值,C++11新标准引入了两个新函数,分别是cbegin和cend
已知的一个限制是不能在范围for循环中向vector对象添加元素。另外一个限制是任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector对象的迭代器失效
3.4.2 迭代器运算
只要两个迭代器指向的是同一个容器中的元素或者尾元素的下一位置,就能将其相减,所得结果是两个迭代器的距离。所谓距离指的是右侧的迭代器向前移动多少位置就能追上左侧的迭代器,其类型是名为difference_type的带符号整型数。string和vector都定义了difference_type,因为这个距离可正可负,所以difference_type是带符号类型的。
3.5 数组
数组的大小确定不变,不能随意向数组中增加元素。因为数组的大小固定,因此对某些特殊的应用来说程序的运行时性能较好,但是相应地也损失了一些灵活性。
如果不清楚元素的确切个数,使用vector
3.5.1 定义和初始化内置数组
数组中元素的个数也属于数组类型的一部分,编译的时候维度应该是已知的。也就是说,维度必须是一个常量表达式(参见2.4.4节,第58页)
字符数组的特殊性
我们可以用字符串字面值(参见2.1.3节,第36页)对此类数组初始化。当使用这种方式时,一定要注意字符串字面值的结尾处还有一个空字符,这个空字符也会像字符串的其他字符一样被拷贝到字符数组中去
不允许拷贝和赋值
不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值
理解复杂的数组声明
要想理解数组声明的含义,最好的办法是从数组的名字开始按照由内向外的顺序阅读。
3.5.2 访问数组元素
数组的元素也能使用范围for语句或下标运算符来访问。
在使用数组下标的时候,通常将其定义为size_t类型。size_t是一种机器相关的无符号类型,它被设计得足够大以便能表示内存中任意对象的大小。在cstddef头文件中定义了size_t类型,这个文件是C标准库stddef.h头文件的C++语言版本。
3.5.3 指针和数组
使用数组的时候编译器一般会把它转换成指针。
在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针
当使用数组作为一个auto(参见2.5.2节,第61页)变量的初始值时,推断得到的类型是指针而非数组
当使用decltype关键字(参见2.5.3节,第62页)时上述转换不会发生,decltype(ia)返回的类型是由10个整数构成的数组
标准库函数begin和end
C++11新标准引入了两个名为begin和end的函数。这两个函数与容器中的两个同名成员(参见3.4.1节,第95页)功能类似,不过数组毕竟不是类类型,因此这两个函数不是成员函数。正确的使用形式是将数组作为它们的参数
两个指针相减的结果的类型是一种名为ptrdiff_t的标准库类型,和size_t一样,ptrdiff_t也是一种定义在cstddef头文件中的机器相关的类型。因为差值可能为负值,所以ptrdiff_t是一种带符号类型
内置的下标运算符所用的索引值不是无符号类型,这一点与vector和string不一样。
3.5.4 C风格字符串
C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。按此习惯书写的字符串存放在字符数组中并以空字符结束(null terminated)。以空字符结束的意思是在字符串最后一个字符后面跟着一个空字符(’\0’)。一般利用指针来操作这些字符串。
3.5.5 与旧代码的接口
如果执行完c_str()函数后程序想一直都能使用其返回的数组,最好将该数组重新拷贝一份。
使用数组初始化vector对象
允许使用数组来初始化vector对象。要实现这一目的,只需指明要拷贝区域的首元素地址和尾后地址就可以了:
3.6 多维数组
要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。