title: c++学习之字符串向量与数组
date: 2020-07-08 14:00:00
categories: 分类
index_img: /img/articles/vim.jpg
tags:
- 标签1
- 标签2
本文对《Primer C++》中的字符串、向量与数组的零碎知识点进行记录与梳理
字符串、向量与数组
命令空间的using声明
- 头文件不应该包含using声明,因为头文件的内容会被拷贝到所应用头文件的源文件中,如果头文件包含using声明,则每个引用该头文件的源文件都会有此using声明,可能会带来意想不到的命名冲突。
标准库类型string
- 对于string的size函数,返回值的类型为string::size_type,这个类型体现了与机器无关的特性。该类型是无符号类型的值,能够放下任何string对象的大小。注意若表达式中有size函数,在该表达式中就不要使用int类型,防止无符号类型与有符号类型的混用导致的莫名其妙的错误。
- 字符串string对象与字符串字面值相加时,必须确保每个加号(+)的两侧运算对象至少有一个是string。需要注意:字符串字面值与string是不同的类型。比如:
string s1 = "world";
string s2 = "hello" + ", " + s1;
//error: +号两侧的运算对象至少有一个是string
//表达式中,"hello"与", "都为字符串字面值,而非string对象
- 对于c++程序员,使用c语言兼容的标准库时,应该尽量使用cname头文件,而不使用name.h头文件,cname头文件中的名字都输入命令空间std中,而name.h头文件中的名字则不在命名空间std中。
标准库类型vector
- 因为引用不是对象,所有不存在包含引用的vector对象。
- 对vector对象初始化时,使用
()
还是{}
是有区别的,比如:
vector<int> v1(10); //v1具有10个元素,每个元素值为默认初始值0
vector<int> v2{10}; //v2具有1个元素,该元素的初始值为10
vector<int> v3(10,1); //v3具有10个元素,每个元素的初始值为1
vector<int> v4{10,1}; //v4具有2个元素,元素的初始值分别为10与1
- 范围for语句体内不应该改变其所遍历的序列的大小(size)。
- vector对象的下标运算符(
[]
)可用于访问已经存在的元素,但是不能用于添加元素。经常犯的基础错误是:通过下标向为空的vector对象添加元素。注意这与数组是有区别的,应该通过类似push_back成员函数的方式添加元素。只能对确知已经存在的元素执行下标操作。 - 确保下标索引合法的一种有效手段,就是尽可能使用范围for语句。
迭代器
- 如果容器为空,则begin与end成员函数返回的是同一个迭代器,且都是尾后迭代器。
- 在c++语言中,使用迭代器的for循环中判断条件的语句使用
!=
更合适,而不是<
,因为标准库中的所有容器都提供了!=
运算符,而不是所有的容器都提供了<
运算符。 - begin与end返回的具体类型是由对象是否为常量决定的,如果对象是常量,则begin与end返回const_iterator,如果对象不是常量,则返回iterator。而cbegin与cend返回的类型总是const_iterator,无论对象是否为常量。
- 凡是使用了迭代器的循环体,都不要想迭代器所属的容器添加或者删除元素,这样会导致迭代器失效。
- 表示两个迭代器之间距离的数据类型为difference_type,difference_type是有符号的数据类型。
数组
- 数组的维度必须是常量表达式,常见的错误如下:
unsigned int cnt = 10; //cnt不是常量表达式
int arr[cnt]; //error: cnt不是常量表达式,数组声明错误
- 和内置类型的变量一样,如果在函数体内部定义了某种内置类型的数组,则默认初始化会使得数组的各个元素的值未定义。
- 数组的元素必须为对象,因此不存在引用的数组。
- 如果使用字符串字面值初始化字符数组时,字符串字面值的结尾处的空字符将也会被拷贝到字符数组中。比如:
char a1[] = "c++"; //自动添加表示字符串结束的空字符
char a2[6] = "daniel"; //error: 字符数组没有空间存在空字符
- 在使用数组下标时,通常将其定义为size_t类似,size_t类型是一种机器相关的无符号类型,其被设计的足够大,以便表示内存中任意对象的大小。在头文件cstddef中定义了size_t数据类型。
- 在大多数的表达式中,使用数组类型的对象,其实也是使用一个指向该数组首元素的指针。在一些情况下数组的操作实际上就是指针的操作。
- 对数组对象使用decltype关键字时,返回的是数组类型,而不是指针类型:
int arr1[] = {0,1,2,3,4};
decltype(arr1) arr2 = {0,1,2,3,4}; //arr2是一个含有5个整数的数组类型
- 两个指针相减的结果的数据类型为ptrdiff_t,ptrdiff_t是一种定义在cstddef头文件中的机器相关的数据类型,ptrdiff_t是一种有符号类型。
- 对于大多数的应用来说,使用c++的标准库string要比使用c风格字符串更加安全,也更加高效。
- string提供了一个成员函数c_str,返回一个c风格的字符串,即返回一个指针,该指针指向一个以空字符结束的字符数组,该数组存储的数据与string对象中数据一致。
- 使用指针与数组容易出错,现代的c++程序,应该尽量使用vector与迭代器,避免使用内置数组与指针,应该尽量使用string,避免使用c风格的基于数组的字符串。