c++ vector 初始化_什么?还不懂c++vector的用法,你凭什么勇气来的!

82f78ed0d0673dd5216c81dc3a3f2892.png

作者:良知犹存

转载授权以及围观:欢迎添加微信公众号:羽林君

12c097b5bb4c7ef915327e091058d353.png

前言

    今天继续肝C++,一入C++深似海。越学越有意思。今天给大家带来一篇c++vector的介绍,难以置信这篇文章写了我三天,不过总算整理完毕,现在分享给大家。

        模板类vector 和 array是数组的替代品。模板类vector 类似于string类,也是一种动态数组。 在 c++ 中,vector 是一个十分有用的容器。它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。

    在C++ primer plus 这本书中关于vectir不是进行一次性介绍的,而是分别在不同板块使用vctor而去介绍的,今天我就融合起来介绍一些vector的使用。

12c097b5bb4c7ef915327e091058d353.png

vector做一个模板类

    C++语言既有类模板,也有函数模板,其中vector是一个类模板。只有对C++有一定深入的理解才能写出模板。

    模板本身不是类或是函数,相反可以将模板看作编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程叫做实例化,当使用模板时,需要指出编译器应把类或者函数实例化成何种类型。

    对于类模板来说,我们通过提供一些额外的信息,来指定模板到底实例化成什么样的类,需要提供哪些信息由模板决定。而提供信息的方式如下所示,即在模板名字后面跟一对尖括号,在括号上面放上信息。

以vector为例子:

vector<int> ivec; //ivec保存int类型的对象vector Sales_vec;//保存Sales_item类型的对象vector<vector<string>> file; //一个二维数组,该元素的vector对象

    上面的例子中,编译器根据模板vector生成了三种不同的类型:vector>,vector>和vector>>。

vector是模板而非类型,由vector生成的类型必须包含vector中的元素类型,例如vector>,int就是vector元素的类型。

vector能容纳大部分类型的对象作为参数,但是因为引用不是对象,所以不存在包含引用的vector。

vector> int; //是错误的

定义和初始化vector类型

vector v1;  //v1是一个空vector,它潜在的元素是T类型的,执行默认初始化vector v2(v1); //v2中包含有v1所有元素的副本vector v2 = v1;//等价于v2(v1),v2中包含有v1所有元素的副本vector v3(n,val);//v3包含了n个重复的元素,每个元素的初始值都是valvector  v4(n); //v4包含了n个重复执行了值初始化的对象vector  v5{a,b,c...};//v5包含了初始值个数的元素,每个元素被赋予相应的初始值vector  v5={a,b,c...};//等价于 v5{a,b,c...};

    看到第一个初始化例子,初始化了一个空vector,看上去空vector好像没什么用处。但是别忘了,vector是一个数组,在程序运行中,我们是可以很高效的往vector对象中添加元素。事实上,vector最常用方式就是先定义一个空vector,然后当运行时获取到元素,再逐一添加。    

    当然也可以在定义vector对象时指定元素的初始值。例如,允许一个vector对象的元素拷贝给另一个vector对象。此时,新vector对象的元素就是原vector对象对应的副本。注意两个vector对象的类型必须相同。

vector ivec; //初始状态为空vector ivec2(ivec); //把ivec的值拷贝给ivec2vector ivec3 = ivec; //把ivec的元素拷贝给ivec3vector svec(ivec2); //错误:svec的元素时string对象,不是int

列表初始化vector对象

    列表初始化即使用花括号括起来的0个或多个初始元素值被赋给vector对象:

vector<string> article   = {"a","an","the"};vector<string> article1 = ("a","an","the");//错误 不能放置于圆括号内

创建指定数量的元素:

    还可以用vector对象容纳的元素数量和所有元素的统一初始值来初始化vector对象:

vector<int> ivec(10,-1); //10个int类型的元素,每个都被初始化为-1vector<string> svec(10,"hi!");//10个sting类型的元素,每个都被初始化为"hi!"
12c097b5bb4c7ef915327e091058d353.png

vector迭代器功能

    要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

    不过和指针不一样的是,获取迭代器不是使用取地址符,有迭代器的类型同时返回迭代器的成员。比如,这些类型都拥有名为begin和end的成员,其中begin负责返回指向第一个元素的迭代器,

auto b = v.begin(), c = v.end(); //b表示v的第一个元素 c表示v尾元素的下一个位置

end成员则负责返回指向容器"尾元素的下一个位置"的迭代器。这样的迭代器

 指示的是容器的一个不存在的"尾后"元素。

*iter //返回迭代器iter所指元素的应用iter->mem  //解应用iter并获取该元素名为mem的成员,等价于(*iter).mem++iter    //令iter指向容器中的下一个元素--iter    //令iter指向容器的上一个元素

举例子:依次输出text的每一行直至遇到第一个空白行为止

for(auto it =  text.cbegin(); it != text.cend()&& !it->empty();++it)    count << *it <<endl

:cbegin()和cend()是C++11新增的,它们返回一个const的迭代器,不能用于修改元素。

12c097b5bb4c7ef915327e091058d353.png

vector当作容器

    一个容器就是一些特定类型对象的集合。顺序容器类型有vector(可变大小数组,支持快速随机访问,在尾部之外的位置插入或删除元素可能很慢)、deque(双端队列,支持快速随机访问,在头尾插入/删除元素很快)、list(双向列表,只支持双向顺序访问,在list中任何位置进行插入/删除操作速度都很快)、forward_list(单向列表,只支持单向顺序访问,在列表中任何位置进行插入/删除操作速度都很快)、array(固定大小数组,支持快速随机访问,不能添加或删除元素)、string(与vector类似的容器,但专门用于保存字符,随机访问快,在尾部插入/删除速度快)。

向vector对象中添加元素

    对vector对象来说,直接初始化的方式适用于三种情况:初始值已知且数量较少、初始值是另一个vector对象的副本、所有元素的初始值都一样。然后更常见的情况是:创建一个vector对象时并不清楚实际所许需要的元素个数,元素的值也无法确定。还有些时候即使元素的初值已知,但如果这些值的总量较大且各不相同,那么在创建vector对象的时候执行初始化操作也会显得过于繁琐。

    举个例子:如果想创建一个vector对象令其包含从0到9共10个元素,使用列表初始化的方法很容易做到这一点;但如果vector对象所包含的元素是从0到99或者0到999呢?这时候通过列表初始化把所有元素都一一罗列出来就不太合适了。对于此例来说,更好的处理方法是先创建一个空的vector,然后在运行时再利用vector的成员函数push_back向其中添加元素。push_back负责把一个值当成vector对象的尾元素"压到(push)"vector对象的"尾端(back)",例如:

string word;vector<string> text;//空vector对象while(cin>>word)//cin>>word  是对word 进行赋值{    text.push_back(word);//把word添加到text后面 }

    在这上面有进一步优化的空间就是使用emplace_back(顺序容器(如vector、deque、list)新标准引入了三个新成员:emplace_front、emplace和emplace_back,这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back,允许我们将元素放置在容器头部、一个指定位置之前或容器尾部。)

    在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。

    当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。

    emplace_back在引入右值引用,转移构造函数,转移复制运算符之前,通常使用push_back()向容器中加入一个右值元素(临时对象)的时候,首先会调用构造函数构造这个临时对象,然后需要调用拷贝构造函数将这个临时对象放入容器中。原来的临时变量释放。这样造成的问题是临时变量申请的资源就浪费。

所以现在我们可以用emplace_back替换push_back使用,上面例子就可以这么表示:

text.emplace_back(word);//把word添加到text后面

其他的vector操作

v.empty()   //v.size()v[n] //返回v中第n个位置上的元素引用

不能用下标形式添加元素

v[idex] = a; //错误

此外还有好多vector属于容器的操作,大家可以参考容器使用的函数,都是一样的:具体使用另一位朋友写的很详细,我就不多做赘述了,大家可以去看看《vector容器!》

v.capacity();//容器的容量v.size();//返回容器中的元素个数v.resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置;如果容器变短,则末尾超出容器长度的元素被删除v.resize(int num, eles);v.insert(const_iterator pos,ele);//迭代器指向位置pos插入元素elsv.erase(const_iterator pos);//删除迭代器指向的元素v.erase(const_iterator start,const_iteartor end);//删除迭代器从start到end之间的元素v.clear();//删除容器中所有元素 
12c097b5bb4c7ef915327e091058d353.png

vector当作参数

    在C++里很多时候我们会遇到函数想返回两个以上结果的情况,这时候可以用数组(vector)、类来作为容器返回,也可以声明一个全局变量的数组,将数值存放在数组里解决。

使用引用来解决,将vector的引用在函数间传递

这是一个例子,假设我要传入一个数,我的函数的功能是返回这个数后面十个数的序列。

#include#includeusing namespace std;/*输入一个数,返回这个数后面的十个数字序列注意参数的这个 & 符号不能省略*/ void getSequence(int num,vector<int>& sequence){    for(int i=0;i<10;i++){        sequence.push_back(i+num);    }}int main(){    int num=9;    vector<int> sequence;    //在主调函数这边,直接传入该vector变量    getSequence(num,sequence);    //访问该vector的值的时候,也是直接访问即可    for(vector<int>::iterator it=sequence.begin();it!=sequence.end();it++){        cout<endl;    }}

使用vector注意事项:

1、如果你要表示的向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低;

2、Vector 作为函数的参数或者返回值时,需要注意它的写法:

double Distance(vector<int>&a,vector<int>&b)

 其中的“&”绝对不能少!!

12c097b5bb4c7ef915327e091058d353.png

文件处理和vector应用

    主要是尝试在文件中记录和读取信息,中间用到了vector,C++导出excel表格的过程太过繁琐,所以这里直接用很简单的方法导出一个.csv的文本文件,该文件也可用excel打开。

#include#include#include  // 文件流#include#include using namespace std; int main(){   //写文件   ofstream outFile;   outFile.open("data.csv", ios::out);   outFile << "name" << ',' << "age"<< ',' << "hobby" << endl;   outFile << "Mike" << ',' << 18 << ','<< "paiting" << endl;   outFile << "Tom" << ',' << 25 << ','<< "football" << endl;   outFile.close();   //写文件   ifstream inFile("data.csv", ios::in);   string lineStr;   vector< vector<string> > strArray; //vector 类型文string   while(getline(inFile, lineStr)) // 从 inFile 中读取一行,放到 lineStr 中    {       cout<< lineStr<<endl;        stringstream ss(lineStr); //读取内容放置在 ss流 中, 括号相当于初始化       string str;       vector<string> lineArray;        // 按照逗号分隔       while(getline(ss, str, ',')) // ss 中, 按照 “,” 逗号分割将ss 分割成一个个str       {           lineArray.push_back(str);   // 将字符串放置到 line Array           cout<< str<<endl;       }       strArray.push_back(lineArray);    }   getchar();   return 0;}

   outFile.open("data.csv", ios::out);前面的双引号内容为csv文件路径,若没有输入文件路径,则在编译器默认路径下生成一个csv文件。‘

这就是我分享的vector的一些介绍和使用,如果大家有什么更好的思路,也欢迎分享交流哈。

fb2184a43b9ff78b556d7da4050984cc.png

END

推荐阅读

【1】嵌入式的我们为什么要学ROS【2】嵌入式底层开发的软件框架简述 【3】CPU中的程序是怎么运行起来的 必读【4】C++的匿名函数(lambda表达式)【5】阶段性文章总结分析

本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。

de4df5140a7b79dde35740626af9f61d.png

52af50d0addb1ecd901bed87ffd75e4f.png更多分享,扫码关注我

此外CSDN的C++特训营课程正式开始啦,扫码提前占位?

7f58d09788b1b77afea7eec47c702d95.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突发!Python再次卫冕,Java和C下降,你怎么看?

2019年转眼已经大半&#xff0c;在近几个月的榜单中&#xff0c;Python已经走上卫冕的道路&#xff0c;并且与Java的差距拉得更远了一些。以往与Java常呈现你追我赶之势&#xff0c;而这一次则是直接相差了近10%&#xff01;Python的火&#xff0c;有目共睹。Python陆续登上了I…

NLP产品级系统设计模式

摘要&#xff1a; 在本文中&#xff0c;作者从六个方面描述了一些生产NLP系统的常见设计和部署模式。这些是团队为了使产品开发与技术、业务、战略和操作目标保持一致而必须做出的选择或权衡。 摘要&#xff1a;在本文中&#xff0c;作者从六个方面描述了一些生产NLP系统的常见…

2个vector如何合成一个_面试中如何做到不卑不亢,牢记2个要点

文│叨叨HR那点事(文章原创&#xff0c;版权归本作者所有&#xff0c;欢迎个人转发分享)面试的时候什么态度和面试官沟通&#xff1f;这个问题&#xff0c;就像一千个人眼里有一千个哈姆雷特一样&#xff0c;人人都有自己的意见和看法。有人说&#xff0c;面试嘛&#xff0c;当…

机器学习到底是什么?

摘要&#xff1a; 机器学习到底是什么东东&#xff1f;了解一下&#xff01; 关于机器学习最简单的定义来自于Berkeley所表述的:机器学习是AI的一个分支&#xff0c;它探索了让计算机根据经验提高效率的方法。 为了更深刻的理解这一定义&#xff0c;接下来我们将对其进行拆分…

修改服务器时间报错,修改服务器时间linux

修改服务器时间linux 内容精选换一换IPv6的使用&#xff0c;可以有效弥补IPv4网络地址资源有限的问题。如果当前云服务器使用IPv4&#xff0c;那么启用IPv6后&#xff0c;云服务器可在双栈模式下运行&#xff0c;即云服务器可以拥有两个不同版本的IP地址&#xff1a;IPv4地址和…

windows 反弹shell_容器内反弹shell的51种姿势

什么是反弹shell&#xff1f;反弹shell(reverse shell)&#xff0c;就是控制端监听在某TCP/UDP端口&#xff0c;被控端发起请求到该端口&#xff0c;并将其命令行的输入输出转到控制端。reverse shell与telnet&#xff0c;ssh等标准shell对应&#xff0c;本质上是网络概念的客户…

使用Vue.js开发微信小程序:开源框架mpvue解析

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 成全责编 | 阿秃转自 | 美团技术团队企业博客前言mpvue是一款使用Vue.js开发微信小程序的前端框架。使用此框架&#xff0c;开发者将得到完整的 Vue.js 开发体验&#xff0c;同时为H5和小程序提供了代码复用的能力。如果想将…

高并发下Java多线程编程基础

摘要&#xff1a; Java线程同步与异步 线程池 无锁化的实现方案 分布锁的实现方案 分享的目的&#xff1a; 进一步掌握多线程编程和应用的技巧&#xff0c;希望对大家在平时的开发中应对高并发编程有所帮助 Java线程同步与异步 1. 同步相关的方法有 wait, notify, notifyAll 2.…

deebot扫地机器人怎么清洁_扫地机器人清洁力拼杀,科沃斯机器人DEEBOT N3与小米1S对比评测...

“偷懒是第一生产力”&#xff0c;这句看似玩笑的话细细品味起来似乎还是有点道理&#xff0c;扫地机器人产业的逐渐兴盛又一次验证科技改变人们的生活方式。我自己生活中很少有时间去清扫地面&#xff0c;而且我是个很容易制造垃圾的人&#xff0c;几天不扫家里就脏乱的无法直…

机票分享第一篇 机票由何而来

要&#xff1a; 遥想05年刚加入飞猪&#xff0c;有同学问我机票搜索是怎么做的&#xff0c;一时间不知如何回答。转眼三年过去&#xff0c;为了给自己一个交代&#xff0c;抽时间把所负责的业务、系统、心得加以总结&#xff0c;才有了这几篇机票分享的文章。由于所用的技术、架…

java 获取ip地址_老杜带你学Java【第二课】

上期链接&#xff1a;老杜带你学Java【第一课】01写在前面欢迎来到杜老师的「零基础学Java」课堂~今后&#xff0c;我们就是Java软件工程师了。(此处应该有掌声???)本专题为《零基础学Java》专题&#xff0c;将带你学习2020年全新Java零基础教程&#xff0c;由杜老师亲自录制…

【光说不练假把式】今天说一说Kubernetes 在有赞的实践

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 木鱼 on基础保障责编 | 阿秃一、背景我们为什么选择 Kubernetes&#xff1f;因为 Kubernetes 几乎支持所有的容器业务类型&#xff0c;包括无状态应用、有状态应用、任务型和 Daemonset&#xff0c;Kubernetes 也逐渐成为容…

Apache旗下顶级开源盛会 HBasecon Asia 2018将于8月在京举行

摘要&#xff1a; 作为Apache基金会旗下HBase社区的顶级用户峰会&#xff0c;HBaseCon大会是Apache HBase™官方从2012年开始发起和延续至今的技术会议&#xff0c;先后在美国加州、日本东京和中国深圳等地举办&#xff0c;得到了Google、Facebook、雅虎和阿里巴巴等众多全球顶…

r语言查找是否存在空值_关于R包安装你知道多少?

在R语言的学习过程中离不了各种R包的安装与使用&#xff0c;要使用某个R包首先得学会如何安装该R包。对于R包的安装你知道的有多少&#xff1f;你知道如何指定安装路径吗&#xff1f;为何你每次重新打开R绘画都需要重新安装R包&#xff1f;今天小编带你详细理解install.package…

深入理解JAVA虚拟机学习笔记(一)JVM内存模型

摘要&#xff1a; 上周末搬家后&#xff0c;家里的宽带一直没弄好&#xff0c;跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带&#xff0c;可以结束一个多星期没网的痛苦日子了。这段时间也是各种忙&#xff0c;都一个星期没更新博客了&#xff0c;再不写之前那种状…

oracle schema_了解Oracle备份恢复的知识

Oracle架构体系警报日志(alter log)&#xff1a;一个文本日志文件&#xff0c;记录数据库的错误和状态信息&#xff0c;通常情况下&#xff0c;警报日志位于后台转存目标目录中&#xff0c;该目录有数据库参数DIAFNOSTIC_DEST定义的&#xff0c;其中警报日志的格式为alter.log。…

美部长施压堵华为,遭印度电信巨头现场驳斥 ;WhatsApp被曝漏洞:仅凭一张GIF动图黑客便可接管账户……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 每周三次&#xff0c;打卡即…

实现Chrome Devtools调试JavaScript V8引擎

摘要&#xff1a; 最近开发小程序JavaScript的运行时&#xff0c;通过在客户端嵌入JavaScript V8引擎来实现。前端同学需要调试JavaScript代码&#xff0c;正好Chrome浏览器的Devtools是与V8的Inspector调试协议是一脉相承的&#xff0c;理论上是可以使用Chrome Devtools调试Ja…

angular7.2构建包如何兼容ie_Python 小技巧:如何实现操作系统兼容性打包?

转自&#xff1a;Python猫有一个这样的问题&#xff1a;现要用 setuptools 把一个项目打包成 whl 文件&#xff0c;然后 pip install 在 Windows/Linux 两种操作系统上&#xff0c;但是该项目中有一些依赖库只有 Windows 上才有(例如 pywinauto、pywingui、pywinrm)&#xff0c…