美文网首页转发收藏
6. C++ vector容器的使用

6. C++ vector容器的使用

作者: 拂去尘世尘 | 来源:发表于2020-12-28 22:46 被阅读0次

1. 简介

Vector类 是在 java 中可以实现自动增长的对象数组,vector在C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。 ---百度百科

2. 场景实例

在C语言编程中,涉及到声明一个全局数组的时候,经常会遇到一种情况,数组的大小设定多少合适。一般情况下我们会设定一个比较大的值,例如1000甚至更大,主要就是怕在代码运行中,用到该数组时,若数组容量不够,出现越界的情况,从而导致宕机等较为严重的问题。但是设置过大,也会导致内存浪费,虽然不是什么大问题,但这种变量若定义过多,也会导致一笔不小的开销。在C语言中,可以通过动态数组来解决这一问题。但是在一些场景中,用起来较为复杂。


通过实际例子说明问题,声明一个结构体中,其中包含一个数组成员。

/* 因为无法确定name长度,不得不设定一个不可超越的较大值 */
#define NAME_LENGTH_MAX 100
struct STUDENT {
    char years;
    long id;
    char name[NAME_LENGTH_MAX];
};

在此实例中,我们可以发现,结构体STUDENT包含不确定长度的name成员,为了避免代码访问name数组越界,不得不声明一个不可超越的长度。这就会造成资源浪费的情况。一般情况下,可采用下面两种方法优化。


优化1:C语言中采用动态数组优化

struct STUDENT {
    char years;
    long id;
    char *name;
};

struct STUDENT std;

在用到std变量时,必须对std的name成员分配空间,否则会出现野指针问题,在运行时导致机器宕机。可通过malloc等函数对name进行分配空间。使用起来较为复杂。


优化2:C++ vector

struct STUDENT {
    char years;
    long id;
    vector<char> name;
};

用到std变量时,同样需要对name初始化,可采用vector提供的接口push_back赋初值即可。较优化1方案,使用起来方便一些。


3. 基本用法

C++ 中的vector实现实用的接口供开发者选择:

//头文件
#include <vector> 
using namespace std;

/* 构造方法 */
vector<类型>标识符
vector<类型>标识符(最大容量)
vector<类型>标识符(最大容量,初始所有值)
vector(const vector&) 复制vector
vector(begin,end) 复制数组begin到end之间的值到vector

/* E.g.几种较为常用的方法 */
vector<int> num; //int num[]
vector<char> num(5); //char num[];
vector<char> num(5, 1); //char num[] = {1,1,1,1,1};

int num[5]={1,2,3,4,5};
vector<int>num_copy(i+2,i+4);  //int num_copy[] ={3, 4, 5};

vector< vector<int> >num; //二维向量. 这里最外的<>要有空格。否则在比较旧的编译器下无法通过 int [][];

/* 常用接口 摘自 https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html*/
1.push_back 在数组的最后添加一个数据

2.pop_back 去掉数组的最后一个数据

3.at 得到编号位置的数据

4.begin 得到数组头的指针

5.end 得到数组的最后一个单元+1的指针

6.front 得到数组头的引用

7.back 得到数组的最后一个单元的引用

8.max_size 得到vector最大可以是多大

9.capacity 当前vector分配的大小

10.size 当前使用数据的大小

11.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值

12.reserve 改变当前vecotr所分配空间的大小

13.erase 删除指针指向的数据项

14.clear 清空当前的vector

15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)

16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)

17.empty 判断vector是否为空

18.swap 与另一个vector交换数据

4. 实例

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

struct STUDENT {
    char years;
    long id;
    vector<int> name;
};

void show(vector<int> &vec)
{
    cout <<"Value: ";
    int num = 0;

    for (auto i = vec.begin(); i != vec.end(); i++) {
        cout << vec.at(num++) << " ";
    }
    cout << endl;
}

int main()
{
    struct STUDENT stud;
    vector<int> tmp(3, 5) ; //int tmp[] = {5, 5, 5}; 

    tmp.push_back(23);
    cout <<"---- 1st: "; 
    show(tmp);

    tmp.insert(tmp.begin(), 2, 10);
    cout <<"---- 2nd: "; 
    show(tmp);
    
    tmp.pop_back();
    cout <<"---- 3rd: ";
    show(tmp); 
    
    cout <<"---- 4th: " << tmp.capacity()<<endl;
    
    tmp.clear();
    cout <<"---- 5th: ";
    show(tmp);
    
    return 0;
}

输出:

---- 1st: Value: 5 5 5 23 
---- 2nd: Value: 10 10 5 5 5 23 
---- 3rd: Value: 10 10 5 5 5 
---- 4th: 6
---- 5th: Value:

5. 注意

在实际使用中,vector不当的用法可能会导致较为严重的问题:

  • 在使用vector变量时,必须对其初始化赋值才可以使用。若结构体含有vector成员,也必须先对此成员初始化,否则使用时可能会导致dump。

  • 在结构体有vector成员,不可用memset对此结构体进行清零,否则会导致内存泄漏。

按我的理解,C++中的vector 与 C中的 指针 + malloc 类似。只不过vector将动态数组的一系列操作都封装成标准库的接口。如果我们将vector理解成*vector + malloc ,就能够分析出以上问题的原因:

  • 第一个问题理解。vector是一个指针,如果没有初始化赋值,就是一个野指针。那么在使用没有初始化的vector,就如同在使用野指针,会导致宕机。

  • 第二个问题理解。在初始化后,vector就是一个指针指向了一篇连续的内存,如果使用memset对含有vector成员的结构体清零,那么就会改变vector的指向对象,那么之前的内存还没有释放就被丢失掉了,导致内存泄漏。

6. 总结

c++中vector解决了C语言中声明数组时无需确定范围,其实现方式类似于C语言中的动态数组。不过较C++实现了vector的各种接口,其接口功能看起来也比较符合动态数组的功能。

相关文章

  • C++ STL 之 vectot(三)

    今天我们继续更新 C++ STL 中 vector 容器的使用 vector 容器增加元素 vector 容器增加...

  • C++ STL 之 vectot(四)

    今天我们继续更新 C++ STL 中 vector 容器的使用 vector 容器删除元素 使用 clear() ...

  • 6. C++ vector容器的使用

    1. 简介 Vector类 是在 java 中可以实现自动增长的对象数组[https://baike.baidu....

  • C++ STL 之 vectot(二)

    今天我们继续更新 C++ STL 中 vector 容器的使用 vector 迭代器使用 与 array 类似,v...

  • C++ STL 之 vectot(一)

    今天我们将更新 C++ STL 中 vector 容器的使用,之前我们介绍了 array 容器的使用,其实容器之间...

  • c++学习之vector(容器)、priority_queue(

    c++学习之vector(容器) (转刘同学_0116) 使用vector需要包含头文件#include

  • C++ Vector用法

    vector 是向量类型,它可以容纳许多类型的数据,称其为容器。vector 是C++ STL的一个重要容器,使用...

  • 标准模板库-vector

    标准模板库-vector 1. vector简介 vector为C++的STL中的模板数组容器。在使用时需要包含#...

  • C++:vector erase删除符合条件的元素

    绪 C++ vector中实际删除元素使用的是容器vecrot中std::vector::erase()方法。C+...

  • STL学习笔记之容器篇

    容器 条款1:仔细选择你的容器 C++提供了很多可供程序员使用的容器:(1) 标准STL序列容器:vector,...

网友评论

    本文标题:6. C++ vector容器的使用

    本文链接:https://www.haomeiwen.com/subject/zipgnktx.html