C++ Vector详解


前言

在本篇文章中,我们将会学到关于C++中vector的使用方法
其中包括成员函数(构造,析构),迭代器相关的知识,容量(size,resize,capacity,reverse),以及vector的增删查改
vector

  1. vector是表示可变大小数组的序列容器。
  2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素
    进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小。为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
  4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存
    储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
  5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增
    长。
  6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在
    尾添加和删除元素相对高效
    。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list
    统一的迭代器和引用更好

一、vector的定义

单独定义一个vector:

vector < typename > name;

上面这个定义其实相当于是一维数组name[size],只不过其size可以根据需要进行变化,这就是“变长数组”的名字的由来。

这里的typename可以是任何基本类型,例如int、double、char、结构体等,也可以是STL标准容器,例如set、queue、vector等。

下面我们以int为例子:
🌟🌟v1一个空的vector

vector < int > v1

🌟🌟v2这个vector中包含10个int,并且默认初始化为0

vector < int > v2(10);

🌟🌟v3这个vector中包含10个int,并且手动初始化为1

vector < int > v3(10,1);

🌟🌟v4这个vector中采用v2迭代器区间进行开空间和初始化
并且空间大小和初始化内容与v2相同,即v4包含10个int,初始化为0

vector < int > v4(v2.begin(),v2,end())

🌟🌟v5这个vector中采用拷贝构造初始化,并且空间大小和初始化内容与v3相同,即v5包含10个int,初始化为1

vector < int > v5(v3)

🌟🌟v6这个vector中采用了初始化列表初始化,{}中有几个元素就代表开了几个空间,{}中内容表示初始化的值。这是c++11中的语法

vector < int >v6{1,2,3,4};

在这里插入图片描述

二、vector中元素的访问

vector库中提供了两种访问访问方式
✨ ✨operator [ ] 像数组一样进行访问
✨ ✨使用at进行访问,at访问不到元素是抛异常

vector v1{ 1,2,3,4 };
cout << v1[0] << endl;
cout << v1.at(1) << endl;

✨ ✨vecctor::begin() 指向第一个元素
✨ ✨vecctor::end() 指向第最后一个元素的下一个位置
✨ ✨vecctor::rbegin() 反向迭代器,指向元素最后一个元素
✨ ✨vecctor::rend() 反向迭代器,指向元素第一个位置
✨ ✨vector::front() 返回首元素的引用
✨ ✨vector::back() 返回最后一个元素的引用

vector中元素的遍历
😼😼.正常for循环

vector <int> v1{1,2,3,4};
//1.循环遍历
for (int i = 0; i < v1.size(); i++)
{
	cout << v1[i] << " ";
}
cout << endl;

😼😼.范围for


	//2.范围for
	vector <int> v1{1,2,3,4};
	///依次取v1中的值赋值给e,自动判断结束,自动++往后走
	for (auto& e : v1)
	{
		cout <<e << " ";
		
	}	cout << endl;

😼😼.迭代器,也可以使用反向迭代器

     //3.迭代器
     vector <int>::iterator it = v1.begin();
while(it!=v1.end())
{
	(*it) += 2;
	cout << *it << " ";
	it++;
}
cout << endl;

vector < int >::iterator it1=v1.begin();//正向迭代器
vector < int >::reverse_iterator it2=v2.rbegin();//反向迭代器
vector < int >::const_iterator it3=v3.begin();//const正向迭代器
vector < int >::const_reverse_iterator it3=v3.begin();//const反向迭代器
这些我们也可以用auto来代替,自动推倒类型

这三种方式不仅能访问vector的每一个元素,并且还可以对元素进行修改

三、vector中空间增长

在vector中有空间的大小,容量等概念,我们来一一学习一下

🔱🔱size 用于计算vector中数据个数

	vector<int> v(10);
	cout << v.size() << endl;

最终结果输出10

🔱🔱resize 改变size的大小,开空间同时进行初始化

  vector<int> v;
  for (int i = 1; i < 10; i++)
	  v.push_back(i);

  v.resize(5);
  //剩下的初始化为100
  v.resize(8, 100);
  //剩下的初始化为0
  v.resize(12);

  cout << "v contains:";
  for (size_t i = 0; i < v.size(); i++)
	  cout << ' ' << v[i];

最终输出结果为v contains: 1 2 3 4 5 100 100 100 0 0 0 0
resize变小时不会改变capacity的大小,resize变大时,capacity也会跟着相应的调整

🔱🔱capacity 获取容量大小
我们来看一下扩容机制

void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

vs2022输出结果为
在这里插入图片描述
g++下输出结果
在这里插入图片描述

我们发现不同平台扩容机制不同,vs按照1.5倍增长,g++按照两倍增长,我们不要固化的认为vector增容就是两倍,具体增长是根据具体需求决定的,vs是PJ版本STL,g++是SGI版本STL。

🔱🔱resreve 只负责开空间,不负责初始化工作
一般用于知道需要多少空间,用reverse一次性开好,这样就可以缓解vector增容的代价缺陷

 void TestVectorExpandOP()
{
   vector<int> v;
   size_t sz = v.capacity();
   v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
   cout << "making bar grow:\n";
   for (int i = 0; i < 100; ++i)
   {
      v.push_back(i);
      if (sz != v.capacity())
      {
          sz = v.capacity();
          cout << "capacity changed: " << sz << '\n';
      }
   }
}

一次性开好需要的空间大小,就可以避免边插入边扩容的问题了
🔱🔱empty 判断vector中是否为空
🔱🔱shrink_to_fit 在size发生巨大变化时,采用shrink_to_fit 调整capacity的大小,使capacity可以与size的大小进匹配
在这里插入图片描述

三、vector中增删查改

🎁🎁push_back 尾插 pop_back尾删

      void TestVector4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	auto it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	v.pop_back();
	v.pop_back();

	it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

输出结果为在这里插入图片描述

🎁🎁find 查找这个并不是在vector库里的,而是算法模块实现的
在这里插入图片描述

🎁🎁insert 进行插入
    ❤️❤️在pos插入value

iterator insert (pos,val);

	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	auto pos = find(v.begin(), v.end(), 3);
	//插入一个数
	if (pos != v.end())
	{
		v.insert(pos, 10);
	}
	pos = find(v.begin(), v.end(), 2);

    ❤️❤️在pos位置插入n个相同的值value

void insert ( pos, n, val);


	//插入多个值
	if (pos != v.end())
	{
		v.insert(pos, 2,100);
	}

    ❤️❤️在pos位置插入一段迭代器区间

void insert (pos, first, last);

    //插入一个迭代器区间
   vector<int>vv{ 20,30,40 };
   pos = find(v.begin(), v.end(), 1);
   if (pos != v.end())
   {
	   v.insert(pos, vv.begin(), vv.end());
   }

🎁🎁erase 删除值
    ❤️❤️删除pos位置的值

erase (pos);

   pos = find(v.begin(), v.end(), 30);
   v.erase(pos);

    ❤️❤️删除一段迭代器区间

erase (first,last);

     v.erase(v.begin(), v.begin() + 3);

🎁🎁swap 交换两个vector

void swap (vector& x);

    void test6()
  {
    	vector<int>v1{ 1,2,3,4 };
	    vector<int>v2{ 10,20,30,40 };
	    v1.swap(v2);
  }

在这里插入图片描述

🎁🎁clear 将size设置为零,capacity不变

cla

总结

以上就是今天要讲的内容,本文仅仅详细介绍了C++vector库的系列使用方法,希望对大家的学习有所帮助,仅供参考 如有错误请大佬指点我会尽快去改正 欢迎大家来评论~~ 😘 😘 😘 😘

  • 15
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
C++中的vector是一个动态数组,可以在运行时动态地增加或减少其大小。它提供了许多方便的方法来操作数组,例如在末尾添加元素、在任意位置插入元素、删除元素等等。下面是一些常用的vector操作: 1. 创建vector对象:可以使用默认构造函数创建一个空的vector对象,也可以使用带有初始值的构造函数创建一个包含初始值的vector对象。 ```c++ // 创建一个空的vector对象 std::vector<int> v1; // 创建一个包含初始值的vector对象 std::vector<int> v2 = {1, 2, 3}; ``` 2. 访问vector元素:可以使用下标运算符[]或at()方法来访问vector中的元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 使用下标运算符[]访问元素 int x = v[0]; // x = 1 // 使用at()方法访问元素 int y = v.at(1); // y = 2 ``` 3. 在末尾添加元素:可以使用push_back()方法在vector的末尾添加一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在末尾添加一个元素 v.push_back(4); // v = {1,2, 3, 4} ``` 4. 在任意位置插入元素:可以使用insert()方法在vector的任意位置插入一个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 在第二个位置插入一个元素 v.insert(v.begin() + 1, 4); // v = {1, 4, 2, 3} ``` 5. 删除元素:可以使用erase()方法删除vector中的一个或多个元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 删除第二个元素 v.erase(v.begin() + 1); // v = {1, 3} // 删除第二个到第三个元素 v.erase(v.begin() + 1, v.begin() + 3); // v = {1} ``` 6. 获取vector大小:可以使用size()方法获取vector中元素的数量。 ```c++ std::vector<int> v = {1, 2, 3}; // 获取vector大小 int size = v.size(); // size = 3 ``` 7. 清空vector:可以使用clear()方法清空vector中的所有元素。 ```c++ std::vector<int> v = {1, 2, 3}; // 清空vector v.clear(); // v = {} ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lim 鹏哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值