vector向量是序列容器,表示可以改变大小的数组。就像数组一样,向量为它们的元素使用连续的存储位置,这意味着它们的元素也可以使用指向其元素的常规指针上的偏移量来访问,并且与数组一样高效。但与数组不同,它们的大小可以动态变化,容器会自动处理它们的存储。
在内部,向量使用动态分配的数组来存储它们的元素。这个数组可能需要重新分配,以便在插入新元素时增加大小。
vector底层定义通用的模板为:
template < class T, class Alloc = allocator<T> > class vector;
模板的定义以关键字template开始,后跟一个模板参数列表,这是一个逗号分隔第一个或者多个模板参数的列表,而vector通用模板则用两个模板参数,分别是:
T
放元素的类型。只有在保证T在移动时不会抛出时,实现才能优化移动元素,而不是在重新分配时复制它们。别名为成员类型vector::value_type。
Alloc
用于定义存储分配模型的分配器对象的类型。默认情况下,使用的是分配器类模板,它定义了最简单的内存分配模型,并且是独立于值的。
别名为成员类型vector::allocator_type。
vector的迭代器有如下:
1、begin:返回迭代器到开始(公共成员函数)
2、end:返回迭代器末尾(公共成员函数)
3、rbegin:返回反向迭代器到反向开始(公共成员函数)
4、rend:返回反向迭代器到反向端(公共成员函数)
5、cbegin:将const_iterator返回到开始(公共成员函数)
6、cend:返回const_iterator 末尾(公共成员函数)
7、crbegin:返回const_reverse_iterator到reverse start (公共成员函数)
8、crend :返回const_reverse_iterator到reverse end(公共成员函数)
对每个vector迭代器进行解析
begin公共成员函数如下两种形式:
iterator begin() noexcept;
const_iterator begin() const noexcept;
end公共成员函数如下两种形式:
iterator end() noexcept;
const_iterator end() const noexcept;
begin是序列容器开头的迭代器。end是序列末尾后元素的迭代器。通过一个例子来看,这样更明白begin和end怎么样用。
#include <iostream>
#include <vector>
using namespace std;
#define COUNT 5
int main (int argc, char **argv)
{
vector<int> myvector;
for (int i = 1; i < COUNT; ++i)
{
myvector.push_back(i);//在向量的最后一个元素之后,在其末尾添加一个新元素。
}
for (std::vector<int>::iterator i = myvector.begin(); i != myvector.end(); ++i)
{
cout<<*i <<" ";
}
cout << endl;
return 0;
}
输出结果:
rbegin公共成员函数如下两种形式:
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
rend公共成员函数如下两种形式:
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
rbegin是序列容器的反向开头的反向迭代器,rend是序列容器末尾的反向迭代器。
#include <iostream>
#include <vector>
using namespace std;
#define COUNT 5
int main (int argc, char **argv)
{
int i = 0;
vector<int> myvector(5);//myvector有5个元素,每个的值都是0
for (vector<int>::reverse_iterator rit = myvector.rbegin(); rit != myvector.rend(); ++rit)
{
*rit = ++i;
}
for (vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
{
cout <<*it <<" ";
}
cout << endl;
return 0;
}
输出结果:
vector::cbegin/cend 只有在c++11中才有,跟begin/end用法一样。区别在于iterator 和const_iterator 的区别;
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
std::vector<int> v = {1,2,3,4,5};
for (vector<int>::const_iterator it = v.cbegin(); it != v.cend(); ++it)
{
cout <<" " << *it;
}
cout << endl;
return 0;
}
输出结果:
vector::crbegin/crend在c++11在支持,crbegin是返回指向容器中最后一个元素的const_reverse_iterator,crend是返回指向容器中第一个元素之前的理论元素的const_reverse_iterator;
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector = {1,2,3,4,5}; //myvector有5个元素,值分别为1,2,3,4,5;
for (auto rit = myvector.crbegin(); rit != myvector.crend(); ++rit)
{
cout << " " << *rit;
}
cout << endl;
return 0;
}
输出结果:
vector容量公共成员函数
1、size:返回大小(公共成员函数)
2、max_size: 返回最大大小(公共成员函数)
3、resize:更改大小(公共成员功能)
4、capacity:分配存储容量的返回大小(公共成员函数)
5、empty:测试向量是否为空(公共成员函数)
6、reserve:请求更改容量(公共成员功能)
7、shrink_to_fit:缩小到适合(公共成员功能)
vector::size
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector = {1,2,3,4,5}; //myvector有5个元素,值分别为1,2,3,4,5;
cout <<"size: " <<myvector.size()<<endl;
return 0;
}
输出结果:
max_size
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector; //myvector有5个元素,值分别为1,2,3,4,5;
for (int i = 0; i < 500; ++i)
{
myvector.push_back(i);
}
cout <<"size: " << myvector.size()<<endl;
cout <<"max_size " << myvector.max_size()<<endl;
return 0;
}
输出结果:
resize
void resize (size_type n);
void resize (size_type n, const value_type& val);
调整容器的大小,使其包含n个元素。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector; //myvector有5个元素,值分别为1,2,3,4,5;
for (int i = 1; i < 10; ++i)
{
myvector.push_back(i);
}
myvector.resize(5);
myvector.resize(8,66); //不会覆盖原先1,2,3,4,5的值
for (int i = 0; i < myvector.size(); ++i)
{
cout<<" "<<myvector[i];
}
cout << endl;
return 0;
}
输出结果:
capacity
size_type capacity() const noexcept;
返回当前分配给向量的存储空间的大小,用元素表示。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector; //myvector有5个元素,值分别为1,2,3,4,5;
for (int i = 1; i < 10; ++i)
{
myvector.push_back(i);
}
cout <<"capacity: " << myvector.capacity()<<endl;
return 0;
}
输出结果:
empty
bool empty() const noexcept;
返回是否向量为空
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
int sum = 0;
vector<int> myvector; //myvector有5个元素,值分别为1,2,3,4,5;
for (int i = 1; i <= 10; ++i)
{
myvector.push_back(i);
}
for (auto it = myvector.begin(); it != myvector.end() && !myvector.empty(); ++it)
{
sum += *it;
}
cout <<" sum: " <<sum;
cout << endl;
return 0;
}
输出结果:
reserve
void reserve (size_type n);
reserve()表示请求更改容量,要求向量容量至少足够包含n个元素。如果n大于当前向量容量,该函数将导致容器重新分配其存储,从而将其容量增加到n(或更大)。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int>::size_type sz;
vector<int> foo;
sz = foo.capacity();
for (int i=0; i<100; ++i)
{
foo.push_back(i);
if (sz != foo.capacity())
{
sz = foo.capacity();
}
}
cout << "capacity changed: " << sz << endl;
vector<int> bar;
sz = bar.capacity();
bar.reserve(100); // 这是上面foo的唯一区别
for (int i=0; i<100; ++i)
{
bar.push_back(i);
if (sz!=bar.capacity())
{
sz = bar.capacity();
}
}
cout << "capacity changed: " << sz <<endl;
return 0;
}
输出结果:
vector元素访问
1、operator[]:访问元素(公共成员函数)
2、at:访问元素(公共成员函数)
3、front:访问第一个元素(公共成员函数)
4、back:访问最后一个元素(公共成员函数)
5、data:访问数据(公共成员函数)
operator[]
1、reference operator[] (size_type n);
2、const_reference operator[] (size_type n) const;
返回对向量容器中位置为n的元素的引用。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> v(10);
for (int i = 0; i < v.size(); ++i)
{
v[i] = i;
}
//反向
for (int i = 0; i < v.size()/2; ++i)
{
int temp;
temp = v[v.size()-1-i];
v[v.size()-1-i] = v[i];
v[i] = temp;
}
for (auto it = v.begin(); it != v.end(); ++it)
{
cout <<" " <<*it ;
}
cout << endl;
return 0;
}
输出结果:
at
1、reference at (size_type n);
2、const_reference at (size_type n) const;
返回对向量中位置为n的元素的引用。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> v(10);
for (int i = 0; i < v.size(); ++i)
{
v.at(i) = i;
}
for (int i = 0; i < v.size(); ++i)
{
cout <<" " <<v.at(i);
}
cout <<endl;
//反向
for (int i = 0; i < v.size()/2; ++i)
{
int temp;
temp = v.at(v.size()-1-i);
v.at(v.size()-1-i) = v.at(i);
v.at(i) = temp;
}
//输出反向结果
for (auto it = v.begin(); it != v.end(); ++it)
{
cout <<" " << *it;
}
cout << endl;
return 0;
}
输出结果:
vector中front / back
1、vector中front 公有成员函数为两个:
reference front();
const_reference front() const;
返回对向量中第一个元素的引用。
2、vector中back公有成员函数为两个:
reference back();
const_reference back() const;
返回对向量中最后一个元素的引用。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector;
myvector.push_back(78);
myvector.push_back(16);
myvector.front() -= myvector.back(); // 78 - 16 = 62
std::cout << "myvector.front() is now " << myvector.front() << endl;
return 0;
}
输出结果:
vector中的修改器
1、push_back:在末尾添加元素(公共成员函数)
2、pop_back: 删除最后一个元素(公共成员函数)
3、insert:插入元素(公共成员函数)
4、erase:删除元素(公共成员函数)
5、swap:交换内容(公共成员函数)
6、clear:清除内容(公众成员功能)
push_back
void push_back (const value_type& val);
void push_back (value_type&& val);
在向量的最后一个元素之后,在其末尾添加一个新元素。val的内容被复制(或移动)到新元素。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
cout << " myint size: " << v.size()<<endl;
return 0;
}
输出结果:
pop_back
void pop_back();
删除向量中的最后一个元素,有效地将容器大小减少了1。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
int sum = 0;
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
while (!v.empty())
{
sum += v.back();
v.pop_back();
}
cout << " sum: " << sum<<endl;
return 0;
}
输出结果:
insert
(1)iterator insert (const_iterator position, const value_type& val);
(2)iterator insert (const_iterator position, size_type n, const value_type& val);
(3)template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);
(4)iterator insert (const_iterator position, value_type&& val);
(5)iterator insert (const_iterator position, initializer_list<value_type> il);
通过在指定位置的元素之前插入新元素来扩展向量,从而通过插入的元素数量有效地增加容器大小。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector (3,100);
vector<int>::iterator it;
it = myvector.begin();
it = myvector.insert ( it , 200 ); //(1)
myvector.insert (it,2,300); // (2)
it = myvector.begin();
vector<int> anothervector (2,400);
myvector.insert (it+2,anothervector.begin(),anothervector.end()); //(3)
int myarray [] = { 501,502,503 };
myvector.insert (myvector.begin(), myarray, myarray+3); // (3)
cout << "myvector contains:";
for (it=myvector.begin(); it != myvector.end(); it++)
{
cout << " " << *it;
}
cout << endl;
return 0;
}
输出结果:
erase
1、iterator erase (const_iterator position);
2、iterator erase (const_iterator first, const_iterator last);
从向量中删除单个元素(位置)或元素范围([first,last])。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> v;
for (int i = 0; i < 10; ++i)
{
v.push_back(i);
}
v.erase(v.begin()+5);
v.erase(v.begin(),v.begin()+3);
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout <<" " << *it;
}
cout << endl;
return 0;
}
输出结果:
swap
void swap (vector& x);
通过x的内容交换容器的内容,x是另一个相同类型的向量对象。大小可能不同。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> A(2,8); // A 6 6
vector<int> B(3,6); // B 8 8 8
A.swap(B);
cout <<"A: ";
for (int i = 0; i < A.size(); ++i)
{
cout <<" " << A[i];
}
cout << endl;
cout <<"B: ";
for (int i = 0; i < B.size(); ++i)
{
cout <<" " << B[i];
}
cout << endl;
return 0;
}
输出结果:
clear
void clear() noexcept;
从向量中移除所有元素(已销毁),使容器的大小为0。
#include <iostream>
#include <vector>
using namespace std;
int main (int argc, char **argv)
{
vector<int> myvector;
myvector.push_back (100);
myvector.push_back (200);
myvector.push_back (300);
myvector.clear();
myvector.push_back (400);
myvector.push_back (500);
cout <<" contains ";
for (unsigned i=0; i<myvector.size(); i++)
std::cout << " " << myvector[i];
std::cout << endl;
return 0;
}
输出结果:
扫二维码关注微信公众号,获取技术干货