C++ 学习笔记之——STL 库 vector
vector 是一种顺序容器,可以看作是可以改变大小的数组。
就像数组一样,vector 占用连续的内存地址来存储元素,因此可以像数组一样用偏移量来随机访问,但是它的大小可以动态改变,容器会自动处理内存分配问题。
在内部,vector 使用动态分配的数组来存储元素,当新元素插入时,如果现有的存储空间已经占满,则需要重新再分配一个新的数组,并且将之前的元素都移动到新的内存上。这个过程是非常耗时的,因此,vector 并不会在每次插入新元素时都重新分配内存。
相反,vector 容器可能会分配一些额外的内存来适应其大小的增长,因此,其真实容量可能比存储这些元素实际需要的内存要大。库通过不同的策略来平衡内存占用和空间再分配,但无论如何,空间分配只应在 vector 大小以对数增长的时候发生,以便在向量末尾插入单个元素可以做到均摊情况下是常数级的时间复杂度。
因此,相对于数组,vector 会消耗更多的内存来换取更有效地对内存进行管理并且动态增长。
相对于其他动态容器,vector 支持随机访问,并且能相对高效地在末尾插入或者删除元素,但如果要在其他位置插入或者删除元素,vector 就会表现得很差,而且迭代器和引用也不是那么方便。
构造函数
explicit vector (const allocator_type& alloc = allocator_type());
默认构造函数,构造出一个不包含任何元素的空的 vector;explicit vector (size_type n);
构造出一个包含 个元素的 vector,默认会初始化为 0;explicit vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
构造出一个包含 个值为 的 vector;vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
构造出一个包含迭代器 范围内元素的 vector,注意左闭右开;vector (const vector& x);
复制构造函数,构造出一个和 相同的 vector;
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> first; // 空的 vectorvector<int> second (4, 100); // 包含 4 个值为 100 元素的 vector,[100, 100, 100, 100]vector<int> third (second.begin(), second.end()); // 包含 second 起始迭代器到终止迭代器区间元素的 vector,[100, 100, 100, 100]vector<int> fourth (third); // 对 third 的复制,[100, 100, 100, 100]// 数组也可以用来作为迭代器初始化 vectorint myints[] = {16, 2, 77, 29};vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ); //[16, 2, 77, 29]vector<int> sixth (4); // [0, 0, 0, 0]cout << "The contents of fifth are:";for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)cout << ' ' << *it;cout << '\n';return 0;
}
复制代码
赋值运算
赋值运算会给容器赋予新的内容,替换掉旧的内容,同时改变其大小。
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> foo (3,0);vector<int> bar (5,0);bar = foo;foo = vector<int>();cout << "Size of foo: " << int(foo.size()) << '\n'; // 0cout << "Size of bar: " << int(bar.size()) << '\n'; // 3return 0;
}
复制代码
迭代器
iterator begin();
返回指向 vector 中第一个元素的迭代器;iterator end();
返回一个迭代器,引用向量容器中的 past-the-end 元素,也即最后一个元素之后的理论元素;reverse_iterator rbegin();
返回指向 vector 中最后一个元素的反向迭代器,增加反向迭代器会使它们向前移动;reverse_iterator rend();
返回一个反向迭代器,指向向量中第一个元素之前的理论元素;
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> myvector;for(int i = 0; i < 5; i++){myvector.push_back(i);}vector<int>::iterator it = myvector.begin();for (; it != myvector.end(); it++){cout << *it << '\t';}cout << endl;vector<int>::reverse_iterator rit = myvector.rbegin();for (; rit != myvector.rend(); rit++){cout << *rit << '\t';}cout << endl;return 0;
}
// 0 1 2 3 4
// 4 3 2 1 0
复制代码
也可以对向量建立指针,然后通过指针来访问成员函数。或者建立引用。
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> myvector;for(int i = 0; i < 5; i++){myvector.push_back(i);}vector<int> *p = &myvector;p->push_back(5);vector<int>::reverse_iterator rit = p->rbegin();// vector<int>::reverse_iterator rit = (*p).rbegin();for (; rit != p->rend(); rit++){cout << *rit << '\t';}cout << endl;vector<int> &ref_myvector = myvector;ref_myvector.push_back(6);vector<int>::iterator it = ref_myvector.begin();for (; it != ref_myvector.end(); it++){cout << *it << '\t';}cout << endl;return 0;
}
// 5 4 3 2 1 0
// 0 1 2 3 4 5 6
复制代码
容量
size_type size() const;
返回向量中元素的个数;size_type max_size() const;
返回向量中最大可能包含的元素个数,但这只是理论上的;void resize (size_type n, value_type val = value_type());
重新设置向量的大小使之包含 个元素;如果 小于现有向量大小,则只保留前 个元素;如果 大于现有向量大小,那么在末尾插入元素来使向量大小达到 ;如果 大于现有向量容量,那么会自动重新分配内存;size_type capacity() const;
返回向量当前分配的内存可以包含多少个元素;bool empty() const;
返回当前向量是否为空,也就是大小是否为零;void reserve (size_type n);
让向量当前分配的内存至少可以包含 个元素;
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> myvector;cout << "max_size: " << myvector.max_size() << endl;// 添加元素的过程中容量会不断增大for(int i = 0; i < 10; i++){myvector.push_back(i);cout << "size: " << myvector.size() << '\t';cout << "capacity: " << myvector.capacity() << endl;}vector<int> othervector;othervector.reserve(100);// 添加元素的过程中大小不超过 100 就不会增大for(int i = 0; i < 10; i++){othervector.push_back(i);cout << "size: " << othervector.size() << '\t';cout << "capacity: " << othervector.capacity() << endl;}return 0;
}
复制代码
元素访问
reference operator[] (size_type n);
像数组一样访问位置 处的元素,但不会进行边界检测;reference at (size_type n);
访问位置 处的元素,但会进行边界检测;reference front();
返回向量中第一个元素的引用;reference back();
返回向量中最后一个元素的引用;
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> myvector;for(int i = 0; i < 10; i++){myvector.push_back(i);}cout << myvector.front() << endl;cout << myvector.back() << endl;// 此处越界访问向量,不会提示for(int i = 0; i <= myvector.size(); i++){cout << myvector[i] << '\t';}cout << endl;// 此处越界访问向量,会抛出一个 out_of_range 异常for(int i = 0; i <= myvector.size(); i++){cout << myvector.at(i) << '\t';}cout << endl;return 0;
}
复制代码
向量修改
void assign (InputIterator first, InputIterator last);
给向量重新分配迭代器 范围内的元素,注意左闭右开;void assign (size_type n, const value_type& val);
给向量重新分配 个值 的元素;void push_back (const value_type& val);
在向量末尾添加一个元素;void pop_back();
从向量末尾删除一个元素;iterator insert (iterator position, const value_type& val);
在迭代器位置前面插入一个元素,返回指向第一个新插入元素的迭代器;void insert (iterator position, size_type n, const value_type& val);
在迭代器位置前面插入 个值 的元素;void insert (iterator position, InputIterator first, InputIterator last);
在迭代器位置前面插入迭代器 范围内的元素;iterator erase (iterator position);
删除迭代器位置的元素,返回最后一个被删除元素的后面一个元素的迭代器;iterator erase (iterator first, iterator last);
删除迭代器 范围内的元素,返回最后一个被删除元素的后面一个元素的迭代器;void swap (vector& x);
和向量 进行交换,两个向量元素类型相同,但大小可能不同;void clear();
清空向量;
#include <iostream>
#include <vector>using namespace std;int main ()
{vector<int> first;vector<int> second;vector<int> third;first.assign(7, 100); // [100, 100, 100, 100, 100, 100, 100]vector<int>::iterator it;it = first.begin() + 1;second.assign(it, first.end() - 1); // [100, 100, 100, 100, 100]int myints[] = {1776, 7, 4};third.assign(myints, myints + 3); // [1776, 7, 4]cout << "Size of first: " << int (first.size()) << '\n';cout << "Size of second: " << int (second.size()) << '\n';cout << "Size of third: " << int (third.size()) << '\n';vector<int> myvector (3, 100); // [100, 100, 100]it = myvector.begin() + 1;it = myvector.insert(it, 200); // [100, 200, 100, 100],此时 it 指向新插入的元素 200myvector.insert(it, 2, 300); // [100, 300, 300, 200, 100, 100],此时 it 无效了it = myvector.begin();vector<int> anothervector (2, 400); // [400, 400]myvector.insert(it + 2, anothervector.begin(), anothervector.end());// [100, 300, 400, 400, 300, 200, 100, 100]int myarray [] = {501, 502, 503};myvector.insert (myvector.begin(), myarray, myarray + 3);// [501, 502, 503, 100, 300, 400, 400, 300, 200, 100, 100]cout << "myvector contains:";for (it = myvector.begin(); it < myvector.end(); it++)cout << ' ' << *it;cout << '\n';myvector.clear();for (int i = 1; i <= 10; i++) myvector.push_back(i);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]it = myvector.erase(myvector.begin() + 5);// [1, 2, 3, 4, 5, 7, 8, 9, 10],此时 it 指向 6 后面的元素 7it = myvector.erase(myvector.begin(), myvector.begin() + 3);// [4, 5, 7, 8, 9, 10],此时 it 指向 3 后面的元素 4cout << "myvector contains:";for (unsigned i = 0; i < myvector.size(); ++i)cout << ' ' << myvector[i];cout << '\n';return 0;
}
复制代码
参考资料 [http://www.cplusplus.com]
获取更多精彩,请关注「seniusen」!
C++ 学习笔记之——STL 库 vector相关推荐
- 多线程编程学习笔记——任务并行库(二)
接上文 多线程编程学习笔记--任务并行库(一) 三. 组合任务 本示例是学习如何设置相互依赖的任务.我们学习如何创建一个任务的子任务,这个子任务必须在父任务执行结束之后,再执行. 1,示例代码如下 ...
- 台湾大学林轩田机器学习技法课程学习笔记4 -- Soft-Margin Support Vector Machine
红色石头的个人网站:redstonewill.com 上节课我们主要介绍了Kernel SVM.先将特征转换和计算内积这两个步骤合并起来,简化计算.提高计算速度,再用Dual SVM的求解方法来解决. ...
- 多线程编程学习笔记——任务并行库(三)
接上文 多线程编程学习笔记--任务并行库(一) 接上文 多线程编程学习笔记--任务并行库(二) 六. 实现取消选项 本示例学习如何实现基于Task的异步操作进行取消流程,以及在任务真正运行前如何知 ...
- Python学习笔记:requests库
Python学习笔记:requests库 利用requests这个功能强大的网络请求库,可以像浏览器一样发送各种HTTP请求来获取网站的数据. 一.运行环境 1.系统版本:Windows 10 2.P ...
- 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例
** 机器学习knn算法学习笔记使用sklearn库 ,莺尾花实例. 具体knn算法是怎样的我这里就不再详细论述.在这里我注意总结我使用knn算法进行一个分类的分析 ** 分析过程 1.前期准备 引入 ...
- STM32 HAL库学习笔记2 HAL库介绍
STM32 HAL库学习笔记2 HAL库介绍 CMSIS标准 一.再次认识HAL库 HAL库设计思想 HAL库实现方式 以GPIO模块为例 GPIO外设数据类型 GPIO外设接口函数 二.使用HAL库 ...
- 台湾大学林轩田机器学习技法课程学习笔记1 -- Linear Support Vector Machine
红色石头的个人网站:redstonewill.com 关于台湾大学林轩田老师的<机器学习基石>课程,我们已经总结了16节课的笔记.这里附上基石第一节课的博客地址: 台湾大学林轩田机器学习基 ...
- AD20学习笔记3---PCB封装库的创建方法及现有封装调用
前言: 本文学习视频是B站点击率第一的凡亿教育<Altium Designer 20 19(入门到精通全38集)四层板智能车PCB设计视频教程>,视频地址:Altium Designer ...
- c++ 将deque部分元素赋值给vector_《STL源码剖析》学习笔记——序列式容器vector
目录 1.容器的概观与分类 2.vector概述 2.1 vector 的迭代器 2.2 vector数据结构 2.3 vector构造与内存管理 2.4 vector的元素操作 1.容器的概观与分类 ...
- 【C++学习笔记】标准库类型vector
标准库类型vector表示对象的集合,其中多有对象的类型都相同,集合中的每个对象都有一个与之对象的索引用来访问对象,需要注意的是引用不是对象,所以不存在包含引用的vector,因其用来容纳着其他对 ...
最新文章
- ini文件怎么注释_wamp怎么升级php版本
- shell下 使用心得
- Pycharm中tensorflow框架下tqdm的安装
- 解决Inno Setup制作安装包无法创建桌面快捷方式的问题
- 分治法求解最大子数组问题
- 战“疫”期,阿里云云效团队在家高效开发实录
- Java Duration类| 带示例的compareTo()方法
- 前端工程师技能之photoshop巧用系列扩展篇——自动切图
- [转]Express入门教程:一个简单的博客
- Nsight Compute Profile Kernel无法定位源码问题
- 如何助力鸿蒙发展,实话实说:华为以一已之力,能不能推动鸿蒙系统的发展 - 区块网...
- Redis数据倾斜与JD开源hotkey源码分析揭秘
- 蒋涛对话王成录:开发者的黄金十年
- rc4加密问题漏洞修复_服务器SSL不安全漏洞修复方案
- 苹果手机如何只用数据线修改定位
- 记一次苦逼的sql注入
- oracle trace进程,ORACLE SQL_TRACE的使用
- Python 常用的标准库以及第三方库
- 核燃料干式储存容器市场现状及未来发展趋势
- Altium Designer 实用操作笔记
热门文章
- Docker概念学习系列之详谈Docker 的核心组件与概念(5)
- 用Python实现BP神经网络(附代码)
- 用 TStringList 模拟 将字符串转换为变量的功能 - 回复 flq_00000 和 外来天客 的问题...
- .net中即时消息发送的实现
- Java开发笔记(一百二十八)Swing的图标
- SpringMVC使用CommonsMultipartResolver上传文件
- saltstack高效运维
- MySQL中的float和decimal类型有什么区别
- PHP 实现简单购物车功能(2)
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库...