相关文章推荐
读研的水煮鱼  ·  C# 数据操作系列 - 19 ...·  1 年前    · 
痴情的拖把  ·  springBoot整合讯飞星火认知大模型- ...·  1 年前    · 
踢足球的酸菜鱼  ·  Excel技巧—超实用的字符串拆分小技巧_亦 ...·  2 年前    · 
逃跑的椰子  ·  js date日期格式化_js ...·  2 年前    · 
独立的树叶  ·  Swift 泛型 | 菜鸟教程·  2 年前    · 
Code  ›  C++随记(四)---动态数组vector开发者社区
c++ vector 动态 vector初始化
https://cloud.tencent.com/developer/article/1008454
谦和的电池
2 年前
作者头像
TeeyoHuang
0 篇文章

C++随记(四)---动态数组vector

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > Deep learning进阶路 > C++随记(四)---动态数组vector

C++随记(四)---动态数组vector

作者头像
TeeyoHuang
发布 于 2017-12-28 14:50:32
1.2K 0
发布 于 2017-12-28 14:50:32
举报

C++随记(四)---动态数组vector

前面两篇博文简单讲了一下C++通过new分配动态内存的问题。这一节就该轮到vector登场了,说实话我看完C++ Premier Plus的前半部分时(好吧说实话我是去年这个月就看了前半部分,今年这个月准备看完后面几章…也是浪的飞起,为了坚持看完,所以我才写了这些博文),最让我觉得很有意思,妙到可以拍手鼓掌的两个点:①模板类vector;②引用, 这两个东西简直让我服气啊,心里面在想:我靠,还有这种操作?

废话讲太多了,进入正题吧。

1、模板类vector;

vector 是一种动态数组,我们可以在运行阶段设置vector对象的长度!而常规数组是一开始就要把长度给定下来。而且vector还能在末尾附加新数据,还可以在中间插入新数据。基本上,它是使用new创建动态数组的替代品,而且它确实就是用new和delete来管理内存的,但是这种工作是自动完成的,所以你使用vector的时候完全就可以忘掉我前面两篇博文讲的东西,直接拿来vector用就ok了。      4个要点: ①使用vector对象时要包含头文件:#include<vector> ②vector包含在名称空间std中; ③使用时还是应该像数组那样指出它存储的数据类型; ④可以有很多方法来指定它的元素数。

我第一次见到vector是在使用Opencv的时候,经常看见用vector来装东西,对,我理解的就是vector就像一个篮子一样往里面塞东西就行了,这是我的第一印象。 经典的定义语句:

vector<数据类型> 对象名称 (元素个数)

①范例语句:

#include<vector>//这句话千万不要漏掉啊
using namespace std;
int n;
cin>>n;
vector<int> cars(n)

这就是一个典型的例子,这里我想说的,注意我的元素个数n是一个变量,是手动输入的。这就比起数组是一个伟大的进步啊!

你可以试试如果我把最后一行改成 int cars[n];是什么效果,编译器会报错的,告诉你那里不能用变量,因为数组定义的时候要确定元素个数!我觉得这其实是数组一个很过分的要求,我怎么能次次都做到知道需要多少个元素?我定义少了,运行时根本不够用,我定义多了,那不是浪费内存吗?

幸运的是,vector的出现改变了这一情况,我的n不但可以手动输入,而且这个n也可以是通过其他步骤计算出来的n,这就让我能够做到视情况而定嘛,多么nice!而且就算我是在定义的时候才导入了n,假设我的n此刻等于5,但是我后面完全可以增加,减少元素个数,可以让他长成10个元素,也可以让他缩成2个元素,是不是很方便。

②范例语句 事实上我在定义vector的时候完全可以空着元素个数那一个地方不写,

vector<int>  cars;//这是合法的

这下我连n都不用考虑了,更nice了。

vector的基本操作: 以vector<int>  cars; 为例

①向动态数组vector的末尾添加元素—push_back( ):

for( int a = 1; a++ ; a<=5){
 cars.push_bcak( a );
此操作就是在每次循环时,往数组cars的屁股后面装入一个元素a.
 ②动态数组的长度—size( ):
 由于我并未定义cars的长度,如果我现在需要用到它的长度该怎么半呢?

cars.size( );

上面表达式的值就是数组的长度了,函数size( )返回的是容器中元素数目。 ③动态数组的头—begin( ): 可以简单的理解为begin( )函数返回了数组第一个元素的地址(更精确的说法是返回了指向容器第一个元素的迭代器,可以理解迭代器为一个广义的指针)

cars.begin( );//就是我第一个元素cars[0]的地址了,注意也是从0开始算的

④动态数组的屁股—end( ): end( )返回了指向容器尾部元素的迭代器,理解为最后一个元素的地址。

cars. end( );//就是我最后一个元素的地址,此例中就是cars[4]的地址。

⑤插入元素—insert( ): 既然是动态数组,那么除了我常用的从屁股后面按照顺序一个一个添加元素外,也可以在数组中间插入元素。

cars.insert( cars.begin( )+ i , b);在第i+1个元素前面插入b;

这里就用到了cars.begin( )作为第一个元素的地址。自然+i之后就是原来的第i+1个元素的位置插入新的元素。 ⑥删除元素—erase( ): 能插入就能删除:

cars.erase ( cars.begin( )+ i);//删除第i+1个元素

⑦清空—clear( ):

如果觉得一个一个删除太麻烦了,我想把原来这个容器中的东西倒掉,重新装东西,那么: 
cars.clear( );

基本的操作就是这些,平常应该够用了,这里要提到一个问题,既然是vector类是动态数组,那么我用平常普通数组的方式访问其元素是否可以呢?如 cars[2]是否合法? 回答是合法的,我们甚至可以直接对其值进行修改.如: cars[2] = 100; 依然合法,这样的方式似乎合乎我们平时对于数组的概念 不过我更推荐使用成员函数.at() cars.at(2) = 100;这种方式是比较安全的访问方式,这里不详细解释了。至于究竟想用哪个方式,取决于你的具体程序。

特别注意:如果要访问或者修改其中某个元素的值,一定要保证这个位置的元素已经被初始化了,也就是说原来这里有一个值。 我举个例子,比如我定义 vector<int> vec; 然后我想对其进行赋值,vec[2] = 100; 或者vec.at(2) = 100; 这样做程序会报错!!!会提示内存溢出!!vector subscript out of range!  因为一开始并没有说你容器vec究竟有多大,所以vec.at(2)这个位置并没有被分配内存!我们如果直接访问的话就自然有问题了,而push_back( )函数是一个一个的往后接龙,所以不会出现问题,所以要想直接对元素这么搞,必须要初始化vec。

 
推荐文章
读研的水煮鱼  ·  C# 数据操作系列 - 19 FreeSql 入坑介绍-腾讯云开发者社区-腾讯云
1 年前
痴情的拖把  ·  springBoot整合讯飞星火认知大模型-CSDN博客
1 年前
踢足球的酸菜鱼  ·  Excel技巧—超实用的字符串拆分小技巧_亦心Excel的博客-CSDN博客
2 年前
逃跑的椰子  ·  js date日期格式化_js date格式化_小斌语录的博客-CSDN博客
2 年前
独立的树叶  ·  Swift 泛型 | 菜鸟教程
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号