【原创】C++ 动态数组 vector 详解

【原创】C++ 动态数组 vector 详解一 引入引入 略 vector 收录在 STL 里 是一种特殊的数据结构 它的中文名字叫做 动态数组 或者 不定长数组 有时也被翻译成 容器 说白了 vector 就是一个功能强大的数组 下面让我们来体验它强大的功能吧 二 vector 的头文件 vector 收录在 std 库里 所以调用 vector 需要 include vector usi vector

一、引入

 

引入:略

 

vector收录在STL里,是一种特殊的数据结构。它的中文名字叫做“动态数组”或者“不定长数组”,有时也被翻译成“容器”。

说白了,vector就是一个功能强大的数组。下面让我们来体验它强大的功能吧!

 

 

二、vector的头文件

 

vector收录在std库里,所以调用vector需要

#include

using namespace std;

这两个头文件。

 

 

三、vector的声明与构造函数

 

既然是“动态数组”,vector是一个什么数组呢,int?double?或者结构体数组?

我们可以这样声明一个vector:

vector
<数据类型>
动态数组名;

比如:

vector

i;//一个int的动态数组

vector

c;//一个char的动态数组

vector

n;//一个node的动态数组(node是结构体名)

 

如果你想赋初值,你可以:

vector

M(a,b);//在M里装a个b

vector

N(a); //在N里装a个0

 

当然你也可以:

vector

A;

vector

B(A);//一个和A一模一样的动态数组

vector

C(B.begin()+l,B.end()-r);//继承B动态数组
下标[l,B.end()-r)的值,注意,
下标从0开始,begin(),end(),size()三个函数见下文

 

四、vector的析构函数

 

很简单,你可以vector B;//A是某种数据结构,B是动态数组名

如果你想析构它,只需调用B.~vector (); 即可。

也就是说,vector的析构函数是:动态数组名.~vector
<该数组的数据结构>
();

 

 

五、vector的基本操作

 

以vector

v为例:

① v[i]或v.at(i)//返回v[i]的

② v.size();//返回v数组元素总个数

③ v.front();//返回v数组第一个元素的

④ v.back();//返回v数组最后一个元素的

⑤ v.clear();//清空v数组

⑥ v.begin();//返回v数组第一个数的地址

⑦ v.end();//返回v数组最后一个数之后地址

⑧ v.empty();//判断v数组是否为空,是空则返回1(true)非空(有元素)则返回0(false)

⑨ v.swap(v1);//v1是另一个动态数组,将v和v1元素互换

⑩ swap(v,v1);//同

注意:再次重申,vector的下标是从0开始的!

注意:除v[i]外,其余都是vector的自带函数,因此必须添上括号

 

 

五、vector的插入

 

std库提供了好几种插入,这里讲最为常用的三种。

① v.push_back(a);//在v数组的尾部插入数a

比如:

有一个动态数组x:2017 2333

调用x.push_back(666);

则x:2017 2333 666

② v.insert(v.begin()+k,a);//在下标k的前面插入数a,k之后的数依次后退一位

//记住,下标是从0开始的!

比如:

动态数组x:1 2 3 4 5 6 

调用x.insert(x.begin()+2,100);

则x:1 2 100 3 4 5 6 

③ x.insert(x.begin()+k,p,a);//在下标k前插入p个a

 

六、vector的删除

 

也有三种,

① v.pop_back()//删除最后一个元素

② v.erase(v.begin()+k);//删除下标为k的数,返回下一个位置的下标

③ v.erase(v.begin()+l,v.end()-r);//删除下标[l,v.end()-r)的元素

 

七、vector的内存机制

 

vector能装多少个元素呢?它的长度是多长呢?接下来就要简单地介绍一下vector的内存机制。

先介绍几个函数吧:

 

v.capacity();//返回v数组的长度,就相当于int v[20000];的20000

v.resize(k);//将v数组的长度设为k

 

现在让我们来研究一下vector的内存机制。

 

#include 
  
    #include 
   
     #include 
    
      using namespace std; const unsigned int maxn=; vector 
     
       v; int main() { //printf("%d\n",v.capacity()); //v.resize(1000); unsigned int last=v.capacity(); printf("%d\n",last); for(unsigned int i=1;i<=maxn;i++) { v.push_back(i); unsigned int a=v.capacity(); if(a!=last) { printf("%d\n",a); last=a; } } } 
      
     
    
  

 

 

 

 

 

这个验证程序测试了vector的长度上限,现在让我们来看看输出结果:

 

最后程序输出了这一行英文,然后就会崩溃。这句话的大概意思是:程序运行时申请以某种非正常的方式结束它,请联系开发团队以取得更多信息。

 

(也就是说,我们把vector玩爆了。)

 

我们来看看它的规律,我们可以发现,每一次,它的内存都翻了一倍!!

我们再来看看它什么时候翻倍。

在printf(“%d\n”,a);时,再输出此时的v.size();

此时的程序:

 

#include 
  
    #include 
   
     #include 
    
      using namespace std; const unsigned int maxn=; vector 
     
       v; int main() { //printf("%d\n",v.capacity()); //v.resize(1000); unsigned int last=v.capacity(); printf("%d\n",last); for(unsigned int i=1;i<=maxn;i++) { v.push_back(i); unsigned int a=v.capacity(); if(a!=last) { printf("size()=%d -> capacity()=%d\n",v.size(),a); last=a; } } } 
      
     
    
  

 

 

 

 

 

 

此时的输出结果:

 

 

(结尾还是那句英文。。。。)

 

我们可以看到:

设当前v.capacity()=c,v.size()=s;如果s=c+1,那么c就会加倍。

 

这是一个初始长度为0的动态数组,接着我们来看看初始长度不为0的情况。

此时代码:

 

#include 
  
    #include 
   
     #include 
    
      using namespace std; const unsigned int maxn=; const unsigned int beg=1250;//这是可修改的 vector 
     
       v; int main() { v.resize(beg); unsigned int last=v.capacity(); printf("At first , capacity() = %d\n",last); for(unsigned int i=1;i<=maxn;i++) { v.push_back(1); unsigned int a=v.capacity(); if(a!=last) { printf("size()=%d -> capacity()=%d\n",v.size(),a); last=a; } } } 
      
     
    
  

 

 

 

 

 

 

结果(只保留了一部分):

 

多次试验后,我们可以得出结论:

当动态数组内的元素比动态数组长度多一时,动态数组长度翻倍!

也就是说:if(v.size()-1==v.capacity()) v.resize(v.capacity()*2);

 

而长度翻倍是很花时间的。所以说做题的时候,记得事先把vector的长度拉得足够长,以免运行的时候,vector长度翻倍浪费时间。

 

最后一个问题,vector最多能装多少个元素呢?

我们可以用函数:

v.max_size();

来得到。

 

下列是一个常用的数据结构对应的max_size();

 

bool ->

char ->

int->

unsigned int ->

float ->

double->

long long ->

unsigned long long ->

 

⑨


 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220340.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午8:43
下一篇 2026年3月17日 下午8:44


相关推荐

  • java 唯一随机数_JAVA随机数

    java 唯一随机数_JAVA随机数每篇一句稍待秋风凉冷后,高寻白帝问真源。《望岳三首·其二》-唐代-杜甫获取随机数的方式经常使用的大概就下面5种①Math.random():获取随机小数范围:[0.0,1.0)返回的值是double类型②Random类构造方法:Random():建议使用无参构造方法方法:intnextInt(intn):获取[0,n)范围的随机整数③ThreadLocalRan…

    2022年7月26日
    7
  • Java Jad 反编译class文件

    Java Jad 反编译class文件Jad JAvaDecompil 是一个 Java 的反编译器 可以通过命令行把 Java 的 class 文件反编译成源代码

    2026年3月17日
    1
  • 3分钟搞定下载微信视频号视频!无需第三方软件,亲测有效!

    3分钟搞定下载微信视频号视频!无需第三方软件,亲测有效!2020年是视频号的元年,现在2021视频号还处在发展初期,但是它的潜力是巨大的,将来的价值会超过抖音。你在视频号上点赞的视频,你的好友都会看到,这一点非常有利于营销推广。但抖音上的粉丝和微信联系人是割裂的,我们所有的社交关系都在微信上。但是视频号的短视频内容无法像抖音、快手一样,保存本地或者复制作品链接进行解析下载。有没有其他小技巧能绕过视频号未完善的功能,直接保存视频内容呢?当然有,请记住一句话,在android的系统中,视频是所见即所得本文只针对android系统,不需要借助任何第三方软件,

    2022年6月17日
    51
  • 下载jdk文件后缀是.gz而不是.tar.gz怎么办 谷歌浏览器下载jdk

    下载jdk文件后缀是.gz而不是.tar.gz怎么办 谷歌浏览器下载jdk下载jdk文件后缀是.gz而不是.tar.gz怎么办 谷歌浏览器下载jdk

    2022年4月23日
    83
  • C里使用CopyMemory

    C里使用CopyMemorySocket 接收到的 byte 要转换成自定义的 struct 自定义 Struct 转换成 byte 都相当麻烦用循环去转换太浪费时间了 于是想到用 CopyMemory Google 一圈终于搞定下面的代码是在 SnippetCompi 里编译通过的 C 代码 region nbsp Imports nbsp nbsp using nbsp System nbsp nbsp using nbsp S

    2026年3月19日
    2
  • lammps教程:薄膜渗透模拟(3)–不同孔隙率对过滤效果的影响

    lammps教程:薄膜渗透模拟(3)–不同孔隙率对过滤效果的影响本文是薄膜渗透过滤的最后一篇文章:不同孔隙率薄膜建模。孔隙或空位缺陷的建模原理比较简单:删除一定数量的原子就可以。lammps自带delete_atoms可以随机删除一定比例的原子,如果对孔隙或空位的形状、尺寸等有特殊需求,需要用编程的方法删除原子。delete_atomsporosity命令可随时产生设定比例的原子,如删除50%的原子:delete_atomsporositymembrane0.5482793membrane为原子组0.5为删除原子的比例482793为随机数种子

    2025年8月31日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号