目录
前言
Vector类
遍历与初始化vector
vector的扩容机制
vector的对象操作
find与insert
对象数组
前言
string类中还有一些内容需要注意:
STL 的string类怎么啦?
C++面试中string类的一种正确写法
C++ STL string的Copy-On-Write技术
C++的std::string的“读时也拷贝”技术!
Vector类
vector文档:cplusplus.com/reference/vector/vector/
基本概念:vector是表示可变数组(针对int、double等,字符数组去用string)的序列容器
类原型:template <class T,class Alloc = allocator<T> >class vector
class Alloc = allocator<T>(内存池)采用系统提供的默认的就行
注意事项:[]、普通数组和at的区别在于[]利用断言检查不给改错机会,普通数组是抽查的给改错机会,at是异常捕获
以下几个表中的内容与string类中的内容相似,不再一一演示
vector的定义 | |
(constructor)构造函数声明 | 接口说明 |
vector()
(重点)
| 无参构造 |
vector(size_type n, const value_type& val = value_type())
| 构造并初始化n个val |
vector (const vector& x);
(重点)
| 拷贝构造 |
vector (InputIterator first, InputIterator last)
| 使用迭代器进行初始化构造 |
vector iterator的使用 | |
iterator的使用 | 接口说明 |
begin + end |
获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置 的iterator/const_iterator
|
rbegin + rend |
获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的 reverse_iterator
|
vector的增删改查 | |
vector的增删改查 | 接口说明 |
assign | 覆盖 |
push_back | 尾插 |
pop_back | 尾删 |
find | 查找(不是vector的成员接口,使用时要包含algorithm头文件) |
insert | 在指定位置前插入数据 |
erase | 删除指定位置数据 |
swap | 交换两个vector的数据空间 |
clear | 清空数据 |
operator[] | 像数组一样访问 |
遍历与初始化vector
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//初始化
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
//vector<int>(10,1):开始个空间每个空间给个1
//[]重载
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << "";
}
cout << endl;
//迭代器
vector<int>::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
//范围for
for (auto i : v)
{
cout << i << " ";
}
cout << endl;
return 0;
}
vector的扩容机制
1、扩容1.5倍然后取整
#include <iostream>
#include <vector>
using namespace std;
void test_vector2()
{
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 change:" << sz << endl;
}
}
}
int main()
{
test_vector2();
return 0;
}
2、resize和reserve不会缩容,要缩容用shrink_to_fit
#include <iostream>
#include <vector>
using namespace std;
void test_vector2()
{
size_t sz;
vector<int> v;
sz = v.capacity();
v.reserve(100);//提前开空间
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 change:" << sz << endl;
}
}
cout << "-----------------------" << endl;
cout << "reserve尝试对原空间进行缩容 >" << endl;
cout <<"原size >" << v.size() << endl;
cout <<"原capacity >" << v.capacity() << endl;
v.reserve(10);
cout << "后size >" << v.size() << endl;
cout << "后capacity >" << v.capacity() << endl;
cout << "-----------------------" << endl;
cout << "resize尝试对原空间进行缩容 >" << endl;
cout << "原size >" << v.size() << endl;
cout << "原capacity >" << v.capacity() << endl;
v.resize(10);
cout << "后size >" << v.size() << endl;
cout << "后capacity >" << v.capacity() << endl;
cout << "-----------------------" << endl;
cout << "原size >" << v.size() << endl;
cout << "原capacity >" << v.capacity() << endl;
cout << "shrink_to_fit尝试对原空间进行缩容 >" << endl;
v.shrink_to_fit();
cout << "后size >" << v.size() << endl;
cout << "后capacity >" << v.capacity() << endl;
}
int main()
{
test_vector2();
return 0;
}
vector的对象操作
find与insert
#include <iostream>
#include <vector>
#include<string>
#include <algorithm>
using namespace std;
//增删改查
void test_vector3()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
cout << "初始化 >";
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
//找到数组中的3并返回该数据的下标
auto pos = find(v.begin(), v.end(), 3);
if (pos != v.end())//左闭右开才能遍历到数组所有的值
{
v.insert(pos,30);//在pos位置前插入30
}
cout << "在3前插入30后 >";
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
//头插
v.insert(v.begin(), 0);
cout << "头插0 >";
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
//在下标为2的位置插入
v.insert(v.begin() + 2, 20);
cout << "在下标为2的位置插入20 >";
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
string s("abcd");
cout << "头插字符串 >";
v.insert(v.begin(), s.begin(), s.end());
for (auto e : v)//读取ASCII码
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_vector3();
return 0;
}
对象数组
push_back的原型:void push_back(const value_type& val)
- value_type:自适应类型
#include <iostream>
#include <vector>
#include<string>
#include <algorithm>
using namespace std;
//对象数组
void test_vector4()
{
//对象数组
vector<string> v;
//版本一:有名对象
string s1("苹果");
v.push_back(s1);
//版本二:匿名对象
v.push_back(string("香蕉"));
//版本三:隐式类型转换->产生临时对象->将该临时对象传入->val就是string类型对象的引用
//隐式类型转换:字符串->字符数组->调用std::string(const char*)构造临时std::string对象,并将该对象传递给函数
v.push_back("草莓");//版本一二三效果相同
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}
int main()
{
test_vector4();
return 0;
}
在 Visual Studio 中使用
std::string
,通常情况下,当字符串长度小于等于 28 字节时,std::string
对象会将字符串内容存储在对象内部的小缓冲区中。这个小缓冲区被称为 "短字符串优化"。这样可以避免频繁地进行堆分配和释放。对于超过 28 字节的较长字符串,则会动态分配内存来存储其内容,且std::string
对象本身仅保存指向堆上数据的指针。如果有一个包含多个较长字符串的对象数组,并且只关心它们是一个对象数组而不需要了解每个具体元素所在位置或大小细节,那么您可以声明一个
std::vector<std::string>
来存储这些字符串。无论单个std::string
的大小如何,在该向量中每个元素都将是一个完整的std:string
对象。
vector是一个数组模板,除了有对象数组,还可以有链表数组、树数组、以及嵌套vector数组:
树数组:vector<tree> tc
链表数组:vector<list> lc
嵌套vector数组:vector<vector<int>> cc
- 外部vector的T是vector<int>*,内部vector的T是int*
- vector<int>*可以指向多个vector<int>,int*可以指向多个int
- 外部vector实例化出了对象数组,内部vector实例化出了整型数组
~over~