最详细STL(一)vector
vector的本质还是数组,但是可以动态的增加和减少数组的容量(当数组空间内存不足时,都会执行: 分配新空间(容量为2^n)-复制元素-释放原空间),首先先讲讲vector和数组的具体区别
一、vector和数组的区别
- vector封装了很多数组没有的方法,可以更方便的处理数据;数组相比起vector就少了很多
- 二维vector在声明中可以方便的初始化;数组需要用cstring库里面的memset函数来初始化(且只能直接初始化为0或-1)
- 在一维vector和一维数组;内存都是连续的
- 在二维vector中,第二维的内存不是连续的,但是第一维是连续的;二维数组中内存是连续的
下面是样例代码
#include<cstdio> #include<vector> #include<cstring> using namespace std; int main() { // 普通数组的声明并且初始化 int a_arr[3]; memset(a_arr, -1, sizeof(a_arr)); // vector可以更方便的初始化 ,且可以初始化为任何值 vector<int> a_vector(3,50); for(int i=0;i<3;i++) printf("%d ",a_arr[i]); printf("\n"); for(int i=0;i<3;i++) printf("%d ",a_vector[i]); printf("\n"); printf("\n一维上数组和vector的内存都是连续的\n"); // 一维上数组和vector的内存都是连续的 for(int i=0;i<sizeof(a_arr)/sizeof(int);i++) printf("%d ", &a_arr[i]); printf("\n"); for(int i=0;i<a_vector.size();i++) printf("%d ", &a_vector[i]); printf("\n"); int b_arr[3][3]; memset(*b_arr, -1, sizeof(b_arr)); // vector<vector <int > > b_vector(3,(3)); 自动初始化为0 vector<vector <int > > b_vector(3,vector<int>(3,50)); // 初始化为50 printf("\n二维上数组和vector的内存有差异\n"); // 地址是连续的 for(int i=0;i<3;i++) for(int j=0;j<3;j++) printf("b_arr[%d][%d]的地址为:%d\n", i, j, &b_arr[i][j]); // 地址不是连续的 for(int i=0;i<3;i++) for(int j=0;j<3;j++) printf("b_vector[%d][%d]的地址为:%d\n", i, j, &b_vector[i][j]); // 由于地址不是连续的所以下面的访问方式vector不适用 for(int i=0;i<9;i++) printf("%d ",b_arr[0][i]); printf("\n"); for(int i=0;i<9;i++) printf("%d ",b_vector[0][i]); // 至于为什么vector越界访问的第一个值(也就是vector[0][3])总是0,我猜测是为了更快的push,顺便也初始化了 return 0; }
好了,看到了他们的区别现在再来讲讲vector什么时候用?怎么用?用的时候要注意些什么?
二、什么时候用
在需要使用数组而且不能确定数组的容量,但是又不想开太大的普通数组的时候,可以使用vector。
三、怎么用
方法名称 | 解释 |
v.capacity() | 容器容量 |
v.size() | 容器大小 |
v.at(int idx) | 用法和[]运算符相同 |
v.push_back() | 尾部插入 |
v.pop_back() | 尾部删除 |
v.front() | 获取头部元素 |
v.back() | 获取尾部元素 |
v.begin() | 头元素的迭代器 |
v.end() | 尾部元素的迭代器 |
v.insert(pos,elem) | pos是vector的插入元素的位置 |
v.insert(pos, n, elem) | 在位置pos上插入n个元素elem |
v.insert(pos, begin, end) | |
v.erase(pos) | 移除pos位置上的元素,返回下一个数据的位置 |
v.erase(begin, end) | 移除[begin, end)区间的数据,返回下一个元素的位置 |
reverse(pos1, pos2) | 将vector中的pos1~pos2的元素逆序存储 |
下面这段代码可以让大家初步了解到vector的使用,并且观察到vector动态申请数组的过程
#include<cstdio> #include<vector> #include<cstring> using namespace std; int main() { vector<int> a; for(int i=0;i<5;i++) { a.push_back(i); printf("%d %d\n", a.capacity(), a.size()); } printf("\n"); for(int i=0;i<3;i++) { int num = a.back(); a.pop_back(); printf("%d %d %d\n",a.capacity(),a.size(),num); } return 0; }
四、用的时候要注意什么?
- vector自带了insert和erase来再vector中任意位置来插入元素,但是离尾部越远效率越低,所以需要频繁的在元素中任意位置插入删除元素可以选用其它的容器,比如list
- 还有就是通过下标访问的时候不要越界访问。
参考于:https://blog.csdn.net/weixin_41588502/article/details/87978490
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库