字符串
相等性运算符(==和!=)分别检验两个string对象想等或不相等,string 对象相等意味着长度及所包含字符全部相同。关系运算符 <、<=、>、>=分别检验一个string对象是否小于、小于等于、大于、大于等于另一个 string 对象,依照(大小写敏感的)字典顺序:
- 1、如果两个 string 对象的长度不同,而且较短的 string 对象的每个字符都与较长的 string 对象对应位置上的字符相同,就说较短 string 对象小于较长 string 对象
- 2、如果两个 string 对象在某些对应的位置上不一致,则 string 对象比较的结果其实是 string 对象中第一对相异字符比较的结果。
c++11 for 语句
for (declaration : expression)
statement
expression 部分是一个对象,表示一个序列。declaration 部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值。
使用 for 语句改变字符串中的字符
需要将循环变量定义成引用类型。
只处理一部分字符
想访问 string 对象中的单个字符有两种方式:
- 使用下标
- 使用迭代器
string::size_type 类型
size 函数返回一个 string::size_type 类型的值,该配套类型体现了标准库类型与机器无关的特性。具体使用时通过作用域操作符表明名字 size_type 是在类 string 中定义的。
string::size_type 是一个无符号类型的值,而且足够存放下任何 string 对象大小。同时使用该类型进行数值对比时要注意不要和带符号数混用,因为 s.size() < n 在 n 是一个负值的 int 时判断结果基本肯定为 true, 因为负数会自动转换成一个很大的无符号数。
下标运算符([ ])接受的输入参数是 string::size_type 类型的值,表示要访问的字符的位置;返回值是该位置上字符的引用。下表值必须大于等于 0 而小于 s.size(),超过范围则引发不可预知的结果
vector
- 老式声明 vector 元素的 vector 的方式为外层 vector 对象的右尖括号和其他元素类型之间添加空格:
vector<vector <int> >
- 提供初始元素值的列表,只能把初始值都放在花括号里进行列表初始化而不能放在圆括号里:
vector<string>{"a", "b"};
- 值初始化:圆括号可用于同值的初始化
vector<int> v1(10, 1) \\ 十个1的 vector,不填1则默认0
。甚至在列表初始化失败时也会尝试用值初始化处理vector<string> v1{10, "hi"} \\ 十个"hi"的vector
- 使用vector的 size_type时需要先指定它是由哪种类型定义的
vector<int>::size_type
- 只有当元素的值可比较时,vector对象才能被比较
迭代器
基本操作
- 迭代器用于访问容器类型的元素,有迭代器的类型都拥有
begin
和end
的成员,begin
负责返回指向第一个元素的迭代器,end
负责返回指向容器“尾元素的下一个位置(one past the end)的迭代器”,这个迭代器指示了一个本不存在的元素(尾后 off the end 迭代器),仅作标记作用。如果容器为空,则beign
和end
都返回同一个迭代器(尾后迭代器) - 通过
*iter
的方式获得迭代器指向的元素,++iter
、--iter
令迭代器指向上一个/下一个元素
迭代器类型
- 使用
iterator
和const_iterator
来表示
vector<int>::iterator it; // it能读写vector<int>里的元素
vector<int>::const_iterator it2; // it2不能读写vector<int>里的元素
beign
和end
运算符返回的具体类型由对象是否是常量决定,c++11引入了cbegin
和cend
直接获取const_iterator
解引用和成员访问
- 需要带圆括号
(*it).empty()
,或者用箭头运算符->
(it->empty()
)。箭头运算符结合了解引用和成员访问
迭代器失效
- 使用迭代器的循环体中改变迭代器所属容器的对象容量会导致迭代器失效
迭代器运算
- 迭代器加减整数仍是返回迭代器,表示移动了多少个位置。
- 两个迭代器相减获得之间的距离,类型是
difference_type
的带符号整型数。
数组
- 数组不允许拷贝和赋值
- 复杂声明,对数组而言从数组名开始内向外阅读,再从右到左
int *ptrs[10]; // ptrs是指向10个整型指针的数组
int &refs[10] = /* ?*/; // 错误:不存在引用的数组
int (*Parray)[10] = &arr // Parray指向一个含有10个整型的数组
int (&arrRef)[10] = arr // arrRef引用一个含有10个整型的数组
int *(&arry)[10] = ptrs; // arry是数组的引用,该数组有是个整型指针
- 使用数组下标时通常定义为
size_t
类型,与机器无关的无符号类型,被设计的足够大以便表示内存中任意对象的大小。 - 数组名本身可替换成一个指向数组首元素的指针
int ia[] = {0,1,2}
auto ia2(ia); // ia2 是个整型指针,指向ia的第一个元素,类似auto ia2(&ia[0])
decltype(ia) ia3 = {0, 1, 2}; // ia3是含有3个整型数的数组,decltype不会自动转换
- 指针也是迭代器,可通过指向数组元素的指针自增获取下一位元素。但获取尾后指针需要
int *e = &arr[length]
,用越界一位的下标获取。 - c11引入了
begin
和end
两个标准库函数,能方便获取头指针和尾后指针
int *beg = begin(ia);
int *end = end(ia);
- 两个指针相减的结果类型为
ptrdiff_t
的带符号类型,和size_t
一样定义在 cstddef 头文件中,是机器相关的类型。 - 指针指向同一个数组的元素时可以比较大小
- 下标运算符可以处理负值
int *p = &ia[2];
int j = p[1]; // p1等价*(p+1),即ia[3]
int k = p[-2]; // p[-2]即ia[0]