目录
方法2:使用data()访问(较麻烦,仅为了解释二维vector的内部结构)
1.知识回顾
注意到class T为模版,而 class Alloc = allocator<T>有缺省参数,则在默认情况下使用STL自带的空间配置器,其提供内存池
所以实例化vector模版完整的写法示例如下:
vector<int,allocator<int>> arr = { 1,2,3 };//使用默认的空间配置器
但一般第二个参数不写,使用默认空间配置器
2.对比vetcor<char>和string
string比vetcor<char>更专业,string的接口比vector多,而且string能更好兼容C语言的接口函数
成员函数的参数是对象的调用方法
以push_back函数为例,设传入的参数是string
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> v;
//方法1:在外手动构造string对象
string str = "abc";
v.push_back(str);
//方法2:匿名对象当参数
v.push_back(string("abc"));
//方法3:直接使用C风格的字符串,之后会转化为string对象
v.push_back("abc");
return 0;
}
3.迭代器初始化
讲讲CC29.【C++ Cont】STL库:动态顺序表(vector容器)文章没有讲过的初始化方式
vector<int> arr1 = { 1,2,3,4,5,6 };
vector<int> arr2(arr1.begin() + 1, arr1.end() - 1);
arr2为{2,3,4,5}
迭代器可以是指针,因此可以使用C语言的数组元素的指针来初始化:
int arr1[] = {1,2,3,4,5,6};
vector<int> arr2(&arr1[1], &arr1[5]);
arr2为{2,3,4,5}
4.sort函数
之前在CC25.【C++ Cont】初识运算符的重载和sort函数文章讲过sort函数的使用,这里使用迭代器来排序
排升序
sort默认情况下排升序
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> arr = { 1,4,2,5,8,0 };
sort(arr.begin(), arr.end());
return 0;
}
运行结果:
排降序
方法1:使用反向迭代器
反向排升序等价为正向排降序
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> arr = { 1,4,2,5,8,0 };
sort(arr.rbegin(), arr.rend());
return 0;
}
方法2:使用正向迭代器+greater
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> arr = { 1,4,2,5,8,0 };
greater<int> gt;
sort(arr.begin(), arr.end(),gt);
return 0;
}
也可以使用匿名对象,让代码简洁:
sort(arr.begin(), arr.end(), greater<int>());
运行结果:
5.使用vector常见的错误
认为reserve函数修改了size,这个观点是错误的!
有以下错误代码:
#include <vector>
using namespace std;
int main()
{
vector<int> arr = { 1,4,2,5,8,0 };
arr.reserve(20);
arr[10] = 1;
return 0;
}
报越界错误,因为_size<10,operator[ ]只能访问有效数据!
reserve并不修改size,需要改成resize,之后的执行结果:
6.data成员函数
C++11为vector引入data成员函数,可以通过它来访问vector的私有成员变量:内存数组,其返回内存数组中第一个元素的指针
例如:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> arr = { 1,2,3 };
auto ptr = arr.data();
//注意不能越界访问
cout << ptr[0]<<" " << ptr[1] << " " << ptr[2] << endl;
return 0;
}
运行结果:
(地址一样)
7.二维数组的访问元素
方法1:调用两次operator[][]
之前在文章讲过operator[]的重载
以下这几种写法是等价的:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> arr = { {1,2,3},{4,5,6},{7,8,9} };
cout << arr[2][1] << endl;
cout << arr.operator[](2)[1] << endl;
cout << arr[2].operator[](1) << endl;
cout << arr.operator[](2).operator[](1) << endl;
}
运行结果:
方法2:使用data()访问(较麻烦,仅为了解释二维vector的内部结构)
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> arr = { {1,2,3},{4,5,6},{7,8,9} };
auto which_vector = arr.data()+2;
//访问arr[2][1]
auto which_element = which_vector->data()+2;
cout << *which_element<< endl;
return 0;
}
arr中存储了3个vector<int>,要访问arr[2][1]应该先给出第三个vector的指针,使用which_vector存储
再访问第三个vector的最后一个元素,注意不能写成which_vector.data()!!!
因为 which_vector的类型为指向vector<int>的指针,可以使用
cout << typeid(which_vector).name() << endl;
来打印类型:
(注意到结尾的*,代表指针)
指针访问对象的成员函数可以使用"->"或者(*which_vector).成员函数,两种写法的来由参见48.【C语言】结构体补充文章
auto which_element = which_vector->data()+2;
auto which_element = (*which_vector).data()+2;
当然也可以写在一起:
auto which_element = (*(arr.data() + 2)).data()+2;
执行结果: