字符串、向量和数组
1. string
string::size_type
类型
-
size()
函数返回的值类型 -
无符号整型数
-
如果一条表达式有
size()
函数就不要再使用int
,避免混用int
和unsigned
可能带来的问题
注:字符串字面值与
string
是不同的类型
2. vector
vector<int>::size_type
类型
同string
3. 迭代器
vector<int> arr(10);
vector<int>::literator it = arr.begin(); // 第一个位置的迭代器
auto it2 = arr.end(); // 最后一个位置后面的迭代器
注:end返回的迭代器不实际指向某个元素,所以不能对其进行递增或解引用的操作
迭代器类型
vector<int>::iterator it; // it能读写vector<int>中的元素
vector<int>::const_iterator it2; // it2只能读,不能写
-
begin
和end
返回的具体类型由对象是否是常量决定:- 如果对象是常量,返回
const_iterator
- 如果对象不是常量,返回
iterator
- 如果对象是常量,返回
-
cbegin
和cend
返回const_iterator
(C++11)
(*it).empty(); // 解引用it,然后调用结果对象的empty成员方法
it->empty(); // 等价于上面 将解引用和成员访问结合在一起
迭代器失效
使用了迭代器的循环体,不要向迭代器所属的容器添加元素,否则会导致迭代器失效。
迭代器运算
iter1 - iter2
得到两个迭代器之前的距离,结果值类型为difference_type
的带符号整型。
4. 数组
注:不清楚元素的确切个数使用vector
char a[] = "C++"; // 字符数组a会自动添加字符串结束的空字符
复杂数组声明
int *ptrs[10]; // ptrs是含有10个整型指针的数组,指针数组
int &refs[10]; // 不存在引用的数组
int (*Parray)[10] = &arr; // Parray指向一个含有10个整数的数组,数组指针
int (&arrRef)[10] = arr; // arrRef引用一个含有10个整数的数组
int *(&arr1)[10] = ptrs; // arr1是数组的引用,该数组是一个指针数组
数组下标
size_t
类型,无符号类型
指针和数组的关系
-
编译器一般会把数组转换成指针(指向数组首元素)
-
对数组使用
auto
时,得到的类型是指针
int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto ia2(ia); // ia是一个整型指针,指向ia的首元素
- 对数组使用
decltype
时,得到的类型是数组
decltype(ia) ia3 = {5,6,7,8,9,10,11,12,13,14}; // ia3是一个整型数组
指针也是迭代器
-
vector中迭代器的功能,指针都支持
-
C++11引入begin和end函数,类似于容器中的同名成员
指针运算
两个指针相减的结果是它们之间的距离,类型是ptrdiff_t
的带符号类型。
C风格字符串
字符串存放在字符数组中并以空字符结尾。
string
提供一个成员函数c_str
,将string对象转换成C风格字符串
string s("hello");
const char *cs = s.c_str();
多维数组
- 使用范围for语句处理多维数组,除了最内层的循环,其他所有循环的控制变量都是引用类型。
vector<vector<int>>arr (9,28);
for (auto &row : arr)
for (auto col : row)
-
若不使用引用类型,编译器初始化row时会自动将数组形式的元素转化为指针,这样得到的row类型就是int*,此时内层循环就不合法了。
-
多维数组实际上是数组的数组,因此多维数组名转换得到的指针实际上是指向第一个内层数组的指针。