C++ STL标准模板库的总结学习。文章中对于vertor动态数组的比较常见用法进行总结。
复习时间 2021-07-30
- 匿名对象的使用
- swap实际是交换地址-可以用来缩小容量
- resize 缩小不了容量,可以减少元素个数 或者填充
- 单口容器 和 动态增长的方式
- 初始化的方式
当vector空间满的时候,再当插入新元素的时候,vector会重新申请一块更大的内存空间,将原空间数据拷贝到新的内存空间,然后释放旧的内存空间,再将新元素插入到新空间中,以此可以看出vector的空间动态增长效率低。
1 采用动态模板实现,默认构造函数。常见格式 类型<类型> 实例类名称
2 vector v1(arr,arr+sizeof(arr)/sizeof(int)); 这是最常用的方式 传入起始地址 和最后元素地址的后一个
void ceshi(vector<int> v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
}
//四种方式 1
vector<int > v;
vector<int > v;
int arr[] = { 1,2,3,4,5,6 };
//2 最常用
vector<int> v1(arr,arr+sizeof(arr)/sizeof(int));
//3
vector<int> v2(v1.begin(), v1.end());
//4
vector<int> v3(v2);
ceshi(v1);
ceshi(v2);
ceshi(v3);
2021 07 30 补充 vector (20,1);常见初始化大小 和初始值的方式
值得注意的是
assign
成员方法 将区间内数据赋值给本身
int arr[] = { 1,2,3,4,5,6 };
vector<int> v(arr,arr+sizeof(arr)/sizeof(int));//默认构造
//成员方法
vector<int> v1;
v1.assign(v1.begin(), v1.end());//将区间的数据拷贝赋值给本身
2021-07-30: 复习注意
size() 返回容器中的元素个数
empty()判断容器是否为空
resize(int num)重新指定容器长度 超出删除
resize(int num,elem)重新指定长度 不足用elem元素补上
capacity() 判断容器的容量
reserver(int len)容器预留len个元素长度的空间
注意区分容器元素的个数 和 容量的概念
。容器大小>=元素个数
不能每次添加数据 就一直申请空间 拷贝 这样浪费时间 所以不如申请一定大小的空间 。等满了再拷贝
int arr[] = { 1,2,3,4,5,6 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));//默认构造
cout << v.size()<<endl;
if (v.empty()==true)
{
cout << "空" << endl;
}
v.resize(2);//保留2个
v.resize(5, 1);//保存5个 如果没有达到5个 用1填充
cout<<"size"<<v.size()<<endl;//大小
cout << "capacity"<<v.capacity()<<endl;//容量 两者可能不想等 但是容量大于等于大小
at(int idex) 返回索引idex 所指的数据。如果越界 抛出异常
[] 下标的方式区别在于直接运行报错 不抛出异常
front() 返回容器中第一个数据元素
back() 返回容器中最后一个数据元素
int arr[] = { 1,2,3,4,5,6 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));//默认构造
v[0];
v.at[0];
v[1]=4;
v.front();
v.back();
复习:注意insert
push_back(ele) 尾部插入元素
pop_back() 删除最后一个元素
insert(,) 迭代器指向位置pos插入count个元素ele(不是下标注意
)
erase() 删除迭代器指向位置 也可以是区间
vector<int> v;
v.push_back(10);
v.push_back(20);
//头插法
v.insert(v.begin(), 30);
//尾步插入
v.insert(v.end(), 50);
v.insert(v.begin() + 2, 100);// 这个是因为vector支持随机访问
//一般支持数组下标 中括号访问都支持随机访问
//迭代器可以直接+2 +3 -2 -5 操作
v.pop_back(); //删除最后一个元素
v.erase(v.begin());
v.erase(v.begin(), v.end()); //可以删除指定位置 也可以删除指定范围
复习::匿名对象
补充:swap实际上只是指向空间(地址)的交换 ,并没有实际的数据转移
补充:匿名对象 :vertor < int > (v1) 正常写法 vertor< int > v(v1); 少了实例对象名称
首先我们创建了一个vertor容器,通过Pushback的方式添加元素。查看后发现容量的大小是112138还有剩余的空间。接着我们通过resize(10) 强行修改大小,将多出的9990个元素删除,但是容量并没有变化。
最关键的步骤vector
(v).swap(v);
我们可以先看1 .vertor
这表示创建一个匿名对象 (概念:当这条语句结束,v的内存空间直接释放)。通过() 2.(v)
的方式初始化赋值(不懂看上文初始化)3.swap(v)
这种方式去交换两个容器的元素,实际就是交换地址。 最后实现的结果就是旧空间的元素空间被释放
vector<int> v;
for (int i = 0; i < 10000; i++)
{
v.push_back(i);
}
cout << "size" << v.size() << endl;
cout << "capatical" << v.capacity() << endl;
v.resize(10);
cout << "size" << v.size() << endl;
cout << "capatical" << v.capacity() << endl;
//缩小空间
vector<int>(v).swap(v);
cout << "size" << v.size() << endl;
cout << "capatical" << v.capacity() << endl;
//上面步骤是这样的 根据 v创建一个匿名对象 然后调用swap的方法 两个对象
//交换空间 也就是 地址的指向交换
测试如下代码,我们发现当每次添加一个元素,添加到10000。一共需要拷贝24次(动态数组的实现原理)。
如果我们实现知道大概存入数据 可以通过reserve去预留空间
int num = 0;
int* address = NULL;
vector<int> v;
//修改 v.reserve(10000) 预留空间。
for (int i = 0; i < 10000; i++)
{
v.push_back(i);
if (address != &(v[0]))//注意这个地方取地址
{
address = &(v[0]);
num++;
}
}
cout << "num:" << num << endl;
for (vector<int>::iterator it = v.begin();it!=v.end();it++)
{
cout << "数据" <<(*it)<< endl;
}
如有错误,欢迎指出。