一、vector

1.1 vector是什么

vector是C++标准库提供的一个容器类,可以理解为可变长度数组。在初始定义时无需申明长度,可以一直往后填充数据。填充时,vector容器会自动拓宽可用空间。
储存该容器类的头文件是\
vector储存的数据是连续的,和数组一样

一般地,vector拓宽空间时会将已有空间翻倍。

假如vector所处地址没有这么大的连续内存可供使用,编译器会进行内容重分配:寻找一处可存放翻倍后的vector数组的连续空间,将vector数组拷贝过去,时间复杂度是$O(n)$

也因此,有时候使用vector的速度会比使用普通数组慢一点

1.2 vector提供的一些方法

让我们先来看一个具体的vector使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <vector>
using namespace std;

int main(){
vector<int> a={12,33,4};
a.push_back(88);//此处传入的参数是const int& _x,引用的好处是不会再开辟一个空间储存形参
int num=10;
a.push_back(num);
a.pop_back();
for(auto i:a)
cout<<i<<" ";
return 0;
}

输出结果是

1
12 33 4 88 

我们对上述涉及的方法逐一介绍

1.3 vector的初始化

vector的定义通过vector<类型名> 数组名 实现,可以不初始化,也可以初始化,还可以在初始化的时候提供初次内存空间

下面我们来看看几种不同的初始化方式

1
2
3
4
5
vector<int>a1={1,2,3};//普通初始化
vector<int>a2(10);//a2中有10个元素,默认为0,下标索引从0到9
vector<int>a3(10,3);//a3中10个元素,初始值都为3
vector<int>a4;
a4.reserve(10*sizeof(int));//为a4分配10个int类型的空间

补充:只有定义该对象的时候才可以用大括号赋值。
特此申明,以下声明方式会产生偏差

1
2
vector<int>a5[10]
//此处不是表示10个空间大小的vector容器类,而是vector容器类数组,大小为10,类似于链表头数组

1.4 push_back()和pop_back()

vector的使用类似于栈,只能把数据放入尾部以及从尾部清除。
虽然从编译器提示可以看出$push_back()$括号内是引用变量,但只仅是减少空间复杂度的方法,并不是指向这个变量,而是复制一份放到$vector$容器类内部。
需要注意的是,这里的v.push_back和v.pop_back都是无返回值的方法

1.5 范围 for 循环(Range-based for loop)

1
2
for(auto i:a)
cout<<i<<" ";

这是一个范围for循环,$auto$ $i$是在表达式内定义的变量,用来接受容器内的数据($auto$是一种占位符,根据 $i$ 的右值自动决定类型)

这个循环会遍历整个容器。

那么,编译器怎么知道vector的范围呢?

1.6 begin()和end()

这里就用到了两个方法:a.begin()和a.end()

它们的返回值是迭代器的值。

迭代器是专门用来遍历容器的指针,可以用于各种容器。

a.begin()返回一个指向容器首位的迭代器值,也就是说它返回的是

$std::vector::iterator$ (一个指向vector< int >类型的迭代器)

通过对迭代器解引用就可以得到容器首位的值

需要注意的是a.end()返回的是指向容器末位的下一位的迭代器值,也就是说是访问不到的值

范围for循环等价于如下代码

1
2
3
for (auto it = a.begin(); it < a.end(); ++it) {
cout << *it << " "; // 解引用迭代器,输出它指向的值
}

1.61

除了正向遍历之外,C++还提供了负向遍历的迭代器
$a.rbegin()$,指向末尾元素的迭代器,$a.rend()$,指向首位元素前一位的迭代器。
需要注意的是,假如需要加上只读属性,可以用以下方法:
$a.cbegin()$
$a.crbegin()$

1.7 size()

$a.size()$返回容器a中储存元素的个数
假如是二维容器(顺便在此引入二维容器的定义)

1
2
3
4
5
vector<vector<int>> a(10,vector<int>(5,0));
int aNums=a.size();
//a=10;
int aCols=a[0].size();
//aCols=5;

那么,调用size()就会返回当前维度元素的个数

二、 array容器类

$array$类容器与$vector$容器很类似,相同的方面就不多做赘述,只表明它们不同的方面。
储存该容器类的头文件是\

2.1 array容器类的声明

因为array类是一个大小固定的类,所以必须在声明时就表明大小,其他方面与vector同

1
array<int,3> arr;

总结

以上介绍了$vector$变长数组容器和范围$for$循环的基本内容