std vector 测试例子
作者:互联网
话不多说,直接上代码:
#include <iostream>
#include <string>
#include <vector>
//基于C++11及以上的vector初始化及成员函数测试
int main()
{
//vector官方见http://www.cplusplus.com/reference/vector/vector/,一共31个成员函数
//https://blog.csdn.net/qq844352155/category_1765415.html也做了比较详细的分析,虽然我没看,感觉挺全的
/*
* 感悟:
* 20211227:
* (1)提前开足够的capacity重要性,可以避免原始vector重新配置内部的存储器,可以提高代码效率,避免vector的reference、pointers、iterator失效;
* (2)大多数情况下,使用emplace、emplace_back代替insert、push_back
*/
//一、初始化,参考https://www.jianshu.com/p/d058866e0e10
{
//第1种,空初始化
std::vector<int> v1;//size和capacity都是0
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
//第2种,默认初始化
std::vector<int> v2(10);//size和capacity先预留,元素的值动态获取,一开始申请足够的大小以避免后面重新分配内存
std::cout << "size: " << v2.size() << ", capacity: " << v2.capacity() << std::endl;
//第3种
std::vector<int> v3(10, 6);
std::cout << "size: " << v3.size() << ", capacity: " << v3.capacity() << std::endl;
//第4种,初始化列表
std::vector<int> v4_1{ 1,2,3 };
std::vector<int> v4_2 = { 1,8,4,9,3,2,6,5,7,4,2,3,7,9,5 };
std::cout << "size: " << v4_1.size() << ", capacity: " << v4_1.capacity() << std::endl;
std::cout << "size: " << v4_2.size() << ", capacity: " << v4_2.capacity() << std::endl;
//第5种,拷贝初始化(深拷贝)
std::vector<int> v5_1(v4_1);//拷贝后容量和元素都一致
std::vector<int> v5_2 = v4_2;
std::cout << "size: " << v5_1.size() << ", capacity: " << v5_1.capacity() << std::endl;
std::cout << "size: " << v5_2.size() << ", capacity: " << v5_2.capacity() << std::endl;
//第6种,迭代器初始化,不仅仅是vector初始化vector,只要有迭代器的东西都可以用来初始化vector
int array[3] = { 7,8,9 };
std::vector<int> v6_1(v4_2.begin() + 3, v4_2.end() - 2);//类似拷贝初始化
std::vector<int> v6_2 = { v4_2.begin() + 3, v4_2.end() - 2 };//类似初始化列表
std::vector<int> v6_3(std::begin(array) + 1, std::begin(array) + 2);//数组也可以用std::begin()
std::vector<int> v6_4(array, array + 2);//数组也可以省略std::begin()
std::cout << "size: " << v6_1.size() << ", capacity: " << v6_1.capacity() << std::endl;
std::cout << "size: " << v6_2.size() << ", capacity: " << v6_2.capacity() << std::endl;
std::cout << "size: " << v6_3.size() << ", capacity: " << v6_3.capacity() << std::endl;
std::cout << "size: " << v6_4.size() << ", capacity: " << v6_4.capacity() << std::endl;
std::cout << std::endl;
}
//二、往vector中插入元素push_back、emplace_back、insert、emplace
{
/*
1、emplace_back和emplace是C++11才引入的,emplace_back是push_back的改良版,emplace是insert的改良版,
几乎可以完全替代push_back,唯有少数不可,见https://www.zhihu.com/question/387522517/answer/1151720189
2、当使用insert或emplace时,插入位置应该为[0-vector.size()],否则会出错,这里中括号指闭区间
3、往vector中插入元素时,若capacity不够时进行插入,vector的capacity会改变,vector会重新配置内部的存储器,否则不会
*/
std::vector<int> v1{1,2,3};
//v1.reserve(100);//通过开关这一行发现,若capacity不够时进行插入,capacity会改变,否则不会
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.push_back(1); //在末尾插入一个元素
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.insert(v1.end() - 4, 3); //在倒数第4个元素前插入一个元素
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.insert(v1.begin(), 2); //在指定位置,例如在开头插入一个元素
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.insert(v1.end(), 3); //在末尾插入一个元素,等同push_back
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.insert(v1.begin() + 4, 100); //在指定位置,例如在第5个元素前插入一个元素
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.emplace(v1.begin(), 200);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.emplace(v1.begin() + 4, 300);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.emplace(v1.end(), 300);//在末尾插入一个元素,等同emplace_back
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.emplace_back(400);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << std::endl;
}
//三、删除vector中元素,clear、erase、pop_back
{
/*
clear会清空容器中元素,size变为0,但是capacity不变
erase可以删除某一个位置的元素,或者某一段连续位置的元素,size会改变,但是capacity不变
pop_back删除最后一个元素,size会改变,但是capacity不变
*/
std::vector<int> v1{ 1,2,3,4,5,6,7,8,9 };
std::vector<int> v2(v1);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v2.clear();
std::cout << "size: " << v2.size() << ", capacity: " << v2.capacity() << std::endl;
v1.erase(v1.begin() + 0);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.erase(v1.begin() + 0, v1.begin() + 3);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.pop_back();
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << std::endl;
}
//四、关于vector改变大小的几个函数size、resize、capacity、reserve
{
/*
0、英文学习:reserve预留,reverse反转
1、关于size、resize、capacity、reserve
(1)size是指vector中元素的个数,capacity指当前vector能够容纳元素的数量
(2)resize是会改变vector的size和capacity,那么新vector的size就为resize参数大小
如果原vector的size小于resize的参数,里面的元素前面保持不变,后面用默认值或指定值填充
如果原vector的size大于resize的参数,里面保留前n个元素,n为参数大小
如果原vector的capacity小于resize的参数,新vector的capacity就为resize参数大小
如果原vector的capacity大于resize的参数,新vector的capacity不变
(3)reserve只能改变vector的capacity
如果原vector的capacity小于reserve的参数,新vector的capacity就为reserve参数大小
如果原vector的capacity大于reserve的参数,新vector的capacity不变
*/
{
std::vector<int> v1{ 1,2,3 };
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.resize(10, 1);//v1.resize(10);就等同于v1.resize(10, 0);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.resize(9, 2);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.reserve(5);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.reserve(20);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
}
/*
2、要说明的是:
(1)容器的大小一旦超过capacity的大小,vector会重新配置内部的存储器,
导致和vector元素相关的所有reference、pointers、iterator都会失效;
(2)内存的重新配置会很耗时间。
因此,当我们使用vector时,如果能够提前预知其大小或者预知其大概的大小,都应该先使用reserve或resize提前分配一定的capacity
如下例1、例2,程序开销是不一致的,而例3显示了iterator失效的情况
*/
//例1
{
std::vector<int> v;
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(1);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(2);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(3);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
}
//例2
{
std::vector<int> v;
v.reserve(10);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(1);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(2);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
v.emplace_back(3);
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
}
//例3
{
std::vector<int> v{ 1,2,3 };
std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << std::endl;
auto iter = v.begin();
std::cout << "iter: " << *iter << std::endl;
std::cout << "iter: " << *(++iter) << std::endl;
v.emplace_back(4);
//std::cout << "iter: " << *iter << std::endl;//这一句运行直接报错
}
std::cout << std::endl;
}
//五、关于vector元素位置的begin、end、cbegin、cend、rbegin、rend、crbegin、crend
{
/*
其中cbegin、cend、crbegin、crend是C++11新加入
begin()可以理解为第1个元素的前面,begin()+1就是第2个元素的前面,cbegin、rbegin、crbegin类似
end()可以理解为最后1个元素的后面,end()就是倒数第2个元素的后面,cend、rend、crend类似
begin、end: std::vector<int>::iterator
cbegin、cend: std::vector<int>::const_iterator,用const迭代器修改容器的值不被允许
rbegin、rend: std::vector<int>::reverse_iterator
crbegin、crend: std::vector<int>::const_reverse_iterator,用const迭代器修改容器的值不被允许
*/
std::vector<int> v{ 5,6,7,8,9,1,2,3,4 };
auto iter1 = v.begin();//std::vector<int>::iterator
std::cout << "iter: " << *iter1 << std::endl;
auto iter2 = v.end();
std::cout << "iter: " << *--iter2 << std::endl;
*iter1 = 100, std::cout << "iter: " << *iter1 << std::endl;
auto c_iter1 = v.cbegin();//std::vector<int>::const_iterator
std::cout << "c_iter: " << *c_iter1 << std::endl;
auto c_iter2 = v.cend();
std::cout << "c_iter: " << *--c_iter2 << std::endl;
//*c_iter1 = 100, std::cout << "c_iter1: " << *c_iter1 << std::endl;//该操作不被允许
auto r_iter1 = v.rbegin();//std::vector<int>::reverse_iterator
std::cout << "r_iter: " << *r_iter1 << std::endl;
auto r_iter2 = v.rend();
std::cout << "r_iter: " << *--r_iter2 << std::endl;
*r_iter1 = 100, std::cout << "r_iter1: " << *r_iter1 << std::endl;
auto cr_iter1 = v.crbegin();//std::vector<int>::const_reverse_iterator
std::cout << "cr_iter: " << *cr_iter1 << std::endl;
auto cr_iter2 = v.crend();
std::cout << "cr_iter: " << *--cr_iter2 << std::endl;
//*cr_iter1 = 100, std::cout << "cr_iter1: " << *cr_iter1 << std::endl;//该操作不被允许
std::cout << std::endl;
}
//六、操作符[]和=,获取元素的at、front、back
{
//1、操作符[]来获取某个位置的元素,用来读和写
std::vector<int> v{ 5,6,7,8,9,1,2,3,4 };
std::cout << "v[0]: " << v[0] << std::endl;
std::cout << "v[8]: " << v[8] << std::endl;
v[8] = 100;
std::cout << "v[8]: " << v[8] << std::endl;
//2、
//3、at,与[]操作符类似,可以获取某个位置的元素,用来读和写
std::cout << "v.at(1): " << v.at(1) << std::endl;
v.at(1) = 100;
std::cout << "v.at(1): " << v.at(1) << std::endl;
//4、front、back,
//front用来获取容器第一个元素,作用和v[0]、v.at(0)一致
//back用来获取容器最后一个元素,作用和v[v.size() - 1]、v.at(v.size() - 1)一致
auto f = v.front();
auto b = v.back();
std::cout << "f: " << f << std::endl;
std::cout << "b: " << b << std::endl;
std::cout << std::endl;
}
//七、其他成员函数assign、data、empty、get_allocator、max_size、shrink_to_fit、swap
{
{
/*
1、assign
给容器赋值,与vector初始化相似,不同是可以给一个capacity更大的vector初始化前n个元素,或者capacity不足时扩展得更大
*/
std::vector<int> v1{ 1,2,3 };
std::vector<int> v2(v1.begin(), v1.end());
std::vector<int> v3;
std::cout << "size: " << v3.size() << ", capacity: " << v3.capacity() << std::endl;
v3.assign(v1.begin(), v1.end());
std::cout << "size: " << v3.size() << ", capacity: " << v3.capacity() << std::endl;
std::vector<int> v4(1), v5(5);
std::cout << "size: " << v4.size() << ", capacity: " << v4.capacity() << std::endl;
std::cout << "size: " << v5.size() << ", capacity: " << v5.capacity() << std::endl;
v4.assign(v1.begin(), v1.end());
v5.assign(v1.begin(), v1.end());
std::cout << "size: " << v4.size() << ", capacity: " << v4.capacity() << std::endl;
std::cout << "size: " << v5.size() << ", capacity: " << v5.capacity() << std::endl;
std::cout << std::endl;
}
{
/*
2、data
data就是获取一个指向vector元素的指针,与opencv中Mat的data类似
*/
std::vector<int> v1{ 1,2,3 };
auto a = v1.data();
std::cout << "a: " << *(a++) << std::endl;
std::cout << "a: " << *(a++) << std::endl;
std::cout << "a: " << *(a++) << std::endl;
std::cout << "a: " << *(a++) << std::endl;//可以看到超过vector size的值就是不确定的
std::cout << std::endl;
}
{
//3、empty判断vector size的大小
std::vector<int> v1, v2, v3;
v2.reserve(3), v3.resize(3);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << "size: " << v2.size() << ", capacity: " << v2.capacity() << std::endl;
std::cout << "size: " << v3.size() << ", capacity: " << v3.capacity() << std::endl;
std::cout << "v1.empty: " << v1.empty() << std::endl;
std::cout << "v2.empty: " << v2.empty() << std::endl;
std::cout << "v3.empty: " << v3.empty() << std::endl;
std::cout << std::endl;
}
{
//4、get_allocator,返回内存分配器,暂时用不到
std::vector<int> v1;
auto x = v1.get_allocator();
}
{
//5、max_size,容器所能容纳的最大元素数目,这是系统或者库所实施的限制,暂时用不到
std::vector<int> v1;
auto x = v1.max_size();
}
{
/*
6、shrink_to_fit,请求容器降低其容量和size匹配
(1)由编译器决定是否真正释放多余的内存,该方法值是提出请求,是否要实现由编译器说了算
(2)这可能导致重分配,但不会影响其size以及不能改变其元素
*/
std::vector<int> v1;
v1.reserve(3);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
v1.shrink_to_fit();
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << std::endl;
}
{
//7、swap,把两个相同类型的vector交换一下
std::vector<int> v1{ 5,6,7,8,9,1,2,3,4 }, v2{ 1,2,3 };
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << "size: " << v2.size() << ", capacity: " << v2.capacity() << std::endl;
v1.swap(v2);
std::cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << std::endl;
std::cout << "size: " << v2.size() << ", capacity: " << v2.capacity() << std::endl;
std::cout << std::endl;
}
}
return 0;
}
标签:std,cout,iterator,v1,vector,v4,测试 来源: https://blog.csdn.net/luozhichengaichenlei/article/details/122165649