C++ STL vector容器用法

news/2024/11/18 3:33:07/

文章目录

  • 1 vector初始化方法
  • 2 vector容器迭代器
  • 3 data()函数
  • 4 emplace_back()和push_back()的区别
  • 5 insert()函数
  • 6 vector删除元素
  • 参考

1 vector初始化方法

方式1:

std::vector<double> values;//创建空的vcetor
values.reserve(20); //设置容器的内存分配,即至少可以容纳 20 个元素。

方式2:

std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};//创建一个含有 8 个素数的 vector 容器

方式3:

std::vector<double> values(20);//创建拥有20个元素的vector,他们的默认初始值是0
std::vector<double> values(20, 1.0);//创建拥有20个元素的vector,他们的默认值都是1.0

另外:圆括号 () 中的 2 个参数,既可以是常量,也可以用变量来表示,例如:

int num=20;
double value =1.0;
std::vector<double> values(num, value);

方式4:
通过存储元素类型相同的其它 vector 容器,也可以创建新的 vector 容器,例如:

std::vector<char>value1(5, 'c');
std::vector<char>value2(value1);

如果不想复制其它容器中所有的元素,可以用一对指针或者迭代器来指定初始值的范围,例如:

int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 将保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}

部分成员函数的用法:

#include <iostream>
#include <vector>
using namespace std;
int main()
{//初始化一个空vector容量vector<char>value;//向value容器中的尾部依次添加 S、T、L 字符value.push_back('S');value.push_back('T');value.push_back('L');//调用 size() 成员函数容器中的元素个数printf("元素个数为:%d\n", value.size());//使用迭代器遍历容器for (auto i = value.begin(); i < value.end(); i++) {cout << *i << " ";}cout << endl;//向容器开头插入字符value.insert(value.begin(), 'C');cout << "首个元素为:" << value.at(0) << endl;return 0;
}

输出结果为:
元素个数为:3
S T L
首个元素为:C

2 vector容器迭代器

以上在array中所讲的迭代器方法,在vector中同样适用,但是vector迭代器也有自己的独特之处:
1、因为vector可以初始化为空,所以不能使用迭代器对空的vector进行初始化。

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values;int val = 1;for (auto first = values.begin(); first < values.end(); ++first, val++) {*first = val;//初始化的同时输出值cout << *first;}return 0;
}

对于空的 vector 容器来说,begin() 和 end() 成员函数返回的迭代器是相等的,即它们指向的是同一个位置。
所以,对于空的 vector 容器来说,可以通过调用 push_back() 或者借助 resize() 成员函数实现初始化容器的目的。
2、vector 容器在申请更多内存的同时,容器中的所有元素可能会被复制或移动到新的内存地址,这会导致之前创建的迭代器失效
举个例子:

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values{1,2,3};cout << "values 容器首个元素的地址:" << values.data() << endl;auto first = values.begin();auto end = values.end();//增加 values 的容量values.reserve(20);cout << "values 容器首个元素的地址:" << values.data() << endl;while (first != end) {cout << *first;++first;}return 0;
}

运行程序,显示如下信息并崩溃:

values 容器首个元素的地址:0096DFE8
values 容器首个元素的地址:00965560

可以看到,values 容器在增加容量之后,首个元素的存储地址发生了改变,此时再使用先前创建的迭代器,显然是错误的。因此,为了保险起见,每当 vector 容器的容量发生变化时,我们都要对之前创建的迭代器重新初始化一遍:

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int>values{1,2,3};cout << "values 容器首个元素的地址:" << values.data() << endl;auto first = values.begin();auto end = values.end();//增加 values 的容量values.reserve(20);cout << "values 容器首个元素的地址:" << values.data() << endl;first = values.begin();//重新对迭代器进行初始化end = values.end();while (first != end) {cout << *first ;++first;}return 0;
}

运行结果为:

values 容器首个元素的地址:0164DBE8
values 容器首个元素的地址:01645560
123

3 data()函数

data()函数的功能是返回指向容器中首个元素的指针。通过该指针也可以访问甚至修改容器中的元素

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> values{1,2,3,4,5};//输出容器中第 3 个元素的值cout << *(values.data() + 2) << endl;//修改容器中第 2 个元素的值*(values.data() + 1) = 10;cout << *(values.data() + 1) << endl;return 0;
}

运行结果为:

3
10

4 emplace_back()和push_back()的区别

emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

#include <vector> 
#include <iostream> 
using namespace std;
class testDemo
{
public:testDemo(int num):num(num){std::cout << "调用构造函数" << endl;}testDemo(const testDemo& other) :num(other.num) {std::cout << "调用拷贝构造函数" << endl;}testDemo(testDemo&& other) :num(other.num) {std::cout << "调用移动构造函数" << endl;}
private:int num;
};
int main()
{cout << "emplace_back:" << endl;std::vector<testDemo> demo1;demo1.emplace_back(2);  cout << "push_back:" << endl;std::vector<testDemo> demo2;demo2.push_back(2);
}

运行结果为:

emplace_back:
调用构造函数
push_back:
调用构造函数
调用移动构造函数

在此基础上,读者可尝试将 testDemo 类中的移动构造函数注释掉,再运行程序会发现,运行结果变为:

emplace_back:
调用构造函数
push_back:
调用构造函数
调用拷贝构造函数

由此可以看出,push_back() 在底层实现时,会优先选择调用移动构造函数,如果没有才会调用拷贝构造函数。
显然完成同样的操作,push_back() 的底层实现过程比 emplace_back() 更繁琐,换句话说,emplace_back() 的执行效率比 push_back() 高。因此,在实际使用时,建议优先选用 emplace_back()。

5 insert()函数

在这里插入图片描述

#include <iostream> 
#include <vector> 
#include <array> 
using namespace std;
int main()
{std::vector<int> demo{1,2};//第一种格式用法demo.insert(demo.begin() + 1, 3);//{1,3,2}//第二种格式用法demo.insert(demo.end(), 2, 5);//{1,3,2,5,5}//第三种格式用法std::array<int,3>test{ 7,8,9 };demo.insert(demo.end(), test.begin(), test.end());//{1,3,2,5,5,7,8,9}//第四种格式用法demo.insert(demo.end(), { 10,11 });//{1,3,2,5,5,7,8,9,10,11}for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}return 0;
}

6 vector删除元素

在这里插入图片描述

参考

部分内容参考于C语言中文网;一个很不错的编程网站,建议大家多看看。


http://www.ppmy.cn/news/559349.html

相关文章

git 上传下载

文章目录 gitee/GitHub 是用来做什么的&#xff1f;什么时候需要学习上传项目到 gitee&#xff1f;为什么要将本地项目上传到 gitee&#xff1f;创建 gitee 仓库&#xff1a;在本地新建一个项目将仓库拉取到本地使用 idea 实现项目的上传下载gitee 仓库查看 下面我就来为大家介…

动态规划(偏难):李白打酒加强版

李白打酒加强版 问题描述 话说大诗人李白, 一生好饮。幸好他从不开车。 一天, 他提着酒显, 从家里出来, 酒显中有酒 2 斗。他边走边唱: 无事街上走&#xff0c;提显去打酒。 逢店加一倍, 遇花喝一斗。 这一路上, 他一共遇到店 N N N 次, 遇到花 M M M 次。已知最后一次遇到…

认证管理(锐捷网关篇)

大家好&#xff0c;我是小杜&#xff0c;明天又是周末了&#xff0c;按照师傅的“专政”──不允许周末来公司&#xff0c;可以去下现场看下&#xff0c;只能“勉为其难”在家好好休息了&#xff0c;呵呵呵...... 轻轻拍了下自己嘴巴来回神&#xff0c;咱们今天就学习下网关产品…

思科、华为、华三、锐捷的3A tacacs配置

思科&#xff1a; aaa new-model aaa group server tacacs tacacs-group&#xff08;指定3A服务器组&#xff09;  server name ise1  server name ise2 aaa authentication login conlogin local&#xff08;串口用本地密码验证&#xff09; &#xff08;下面设置3A模板…

锐捷telnet登录配置

①组网需求 通过Telnet功能远程登录管理设备。 ②配置要点 需要给交换机配置一个管理IP&#xff0c;如果PC与交换机不是同一个网段&#xff0c;需要给交换机配置一个默认网关需要配置一个enable密码及telnet密码 ③操作步骤 通过Console线登陆交换机&#xff0c;开启交换机…

锐捷无线配置简单手册

锐捷无线配置简单手册 无AC的情况下(胖AP路由模式)组网拓扑配置命令查询命令 无AC的情况下(胖AP路由模式) 无线网络中的AP做路由使用&#xff0c;配置NAT转换&#xff0c;此时无线用户的网关和dhcp从AP获取&#xff0c;上级网络不用做配置改动 组网拓扑 配置命令 注意&#…

锐捷SuperVlan实验配置

Super Vlan配置 创建Vlan vlan range 2,3,4,10,20 配置Vlan10为Super Vlan&#xff0c;Vlan 2,3,4为Sub Vlan vlan 10 supervlan subvlan 2,3,4 配置Sub Vlan的地址范围&#xff08;也可以不配置&#xff09; Vlan 2 subvlan-address-range 192.168.10.10 192.168.10.50 配置S…

【运维实战家】无线三建七优之QoS-锐捷无线

作者&#xff1a;东东 QoS的常见应用 小伙伴们大家好&#xff0c;接上文负载均衡后收到大家的一致好评&#xff0c;本次由东东给大家带来QoS篇&#xff0c;愿您在知识的海洋中乘风破浪。 众所周知&#xff0c;无论是企业、宾馆或是学校、咖啡厅等场景下&#xff0c;我们作为使…