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

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。 如何初始化呢?多用resize( )函数;

vec.resize( 5);

也就是给vec分配5个单位的内存空间,这样你直接对元素进行操作就能找到地方了。

注意:vector的类型不局限于int、double、char等,它包含的元素可以是结构体,也可以是vector,这就是二维动态数组了。

2、二维动态数组

用过MATLAB的同学应该知道,MATLAB对与矩阵操作是非常便捷的,但是C++中并没有矩阵这种概念,于是我们可以自己用二维数组代替矩阵来进行一些简单的操作。普通数组也有二维数组的形式,但依然需要我定义数组的时候就确定好数组大小,使用起来不方便,而二维的vector容器就能很好的解决这个问题。 如

vector<vector<int> > S;

就是一个二维动态数组,第一层vector的元素是 vector<int>,第二层vector的元素是int

现在就可以把它当作矩阵了,比如S[2][3],是第3行第4列的元素,因为数组从0开始

如图,第一个[ 2 ]表示这是第3个(从0开始算)子vector,而[3]表示是第3个子vector中的第4个(从0开始计数)int 元素。 注意如前文中提到,如果要用S[2][3]=10;这样的语句,一定要先对二维数组进行初始化:

上图是我自己的一个程序中用到二维数组时初始化的过程,注意N的值在我初始化二维动态数组之前是已经通过其他算式获得了确定的值了

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xingoo, 一个梦想做发明家的程序员

最长公共子序列

最长公共子序列问题:给定两个序列X={x1,x2,....xm},    Y={y1,y2,yn},找出XY的最长公共子序列 1 最长公共子序列结构   1 x...

16510
来自专栏企鹅号快讯

Python基础知识3:re正则表达式

正则表达式(或RE)是一种小型的、高度专业化的编程语言,内嵌在Python中,仅做字符的匹配。 1、字符类型: 普通字符和元字符; 1)普通字符:大多数的字符和...

1747
来自专栏进击的君君的前端之路

正则表达式

1485
来自专栏编程

Python3:复杂数据结构的排序

排序是非常常见的一个场景,相比于Python2,Python3中的排序有不少优化,今天谈一谈Python3中常见排序场景~~更多细节可参考Ref中的Python...

21810
来自专栏PHP实战技术

这10个问题你一定要会!

echo "\\"" . $str1 . "\\" contains \\"" . $str2 . "\\"";

3959
来自专栏企鹅号快讯

Python序列元素计数的方法,你知道几种?

在Python脚本语言中,数据结构有许多种,常见的数据类型有:序列,映射与集合三大类型,其中序列又分为可变序列和不可变序列,可变序列有2类:列表(List)与字...

19310
来自专栏Echo is learning

python/pandas 正则表达式 re模块

2866
来自专栏小小挖掘机

哇,原来python字符串是这样的!

python中的字符串一直是困扰小编的一大难题,相信大家伙也曾体验过被各种编码支配的恐惧吧。不过没关系,相信你读了这篇文章,一定会对python字符串豁然开朗!...

3605
来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版6.3节有成员变量的类coredump例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

601
来自专栏从流域到海域

《笨办法学Python》 第32课手记

《笨办法学Python》 第32课手记 本节课讲for循环和list,list里类似于c中的数组,但有区别很大。C语言中的数组是数据类型相同的值的集合,list...

1809

扫码关注云+社区