vector容器

vector底层是一个动态数组,包含三个迭代器,start和finish之间是已经使用的空间范围,end_of_storage是整块连续空间包括备用空间的尾部。
vector内存增长机制:当空间不够装下数据时,会自动申请另一片更大的空间,大小为原来的两倍,然后把原来的数据拷贝到新的内存空间,接着释放原来的空间。

当删除数据的时候,存储空间不释放,只是清空里面的数据。

因此,对vector的操作一旦引擎了空间的重新配置,指向原vector的所有迭代器都失效。

(2)vector中的reserve和resize的区别
vector中reserve和resize的区别:
reserve是直接扩充到已经确定的大小,减少多次开启、释放空间。

resize()可以改变空间的大小,也有改变默认值的功能,capacity的大小也会随着改变。

(3)vector中的size和capacity的区别
 size表示当前vector中有多少个元素(finish - start),而capacity函数则表示它已经分配的内存中可以容纳多少元素(end_of_storage - start)。

(4)vector的元素类型可以是引用吗?
  vector的底层实现要求连续的对象排列,引用并非对象,没有实际地址,因此vector的元素类型不能是引用。
(5)vector迭代器失效的情况
  当插入一个元素到vector中,由于引起了内存重新分配,所以指向原内存的迭代器全部失效。

  当删除容器中一个元素后,该迭代器所指向的元素已经被删除,那么也造成迭代器失效。erase方法会返回下一个有效的迭代器,所以当我们要删除某个元素时,需要it=vec.erase(it);。

(6)正确释放vector的内存(clear(), swap(), shrink_to_fit())
  vec.clear():清空内容,但是不释放内存。

  vector().swap(vec):清空内容,且释放内存,相当于得到一个全新的vector。

  vec.shrink_to_fit():请求容器降低其capacity和size匹配。

  vec.clear();vec.shrink_to_fit();:清空内容,且释放内存。

实践代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template<typename T>
void coutall(vector<T> &vct)
{
    //使用auto,请确保编译器支持C++11
    for(auto it = vct.begin();it != vct.end();it++)
    {
        cout<< *it << "  ";
    }
    cout <<endl;
}

int main() {
    cout << "STL VECTOR TEST START!\n";
    //初始化
    vector<int> vec_name1;
    vector<int> vec_name2(vec_name1);
    vector<int> vec_name3(100,1);
    vector<int> vec_name4(100);//默认值会是0
    
    //C++标准11,可用数组对vector赋初值初始化
    vector<int> vec_name5{1,2,3,4};
    
    int arr[]={0,1,2,3,4};
    vector<int> vec_name6(begin(arr),end(arr));
    char arr2[]="abcde";
    vector<char> vec_name7(begin(arr2),end(arr2));
    
    //使用迭代器遍历,最上面也有封装遍历打印函数
    vector<int>::iterator it;
    for( it=vec_name3.begin();it!=vec_name3.end();++it)
    {
        cout<<*it<<" ";
    }
    coutall(vec_name7);

    //设置空间大小 reserve 和resize  查看元素个数和空间大小
    vec_name3.reserve(200);
    vec_name4.resize(200,1);

    cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
    cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
    
    cout<<"vec_name4.size ="<<vec_name4.size()<<endl;
    cout<<"vec_name4.capacity ="<<vec_name4.capacity()<<endl;
    
    vec_name3.reserve(150);//该语句的修改不会生效,也不会报错,因为150小于当前capacity200
    cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
    cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;

    //判断是否为空
    cout<<"vec_name1.empty = "<<vec_name1.empty()<<endl;
    cout<<"尾部添加元素 pop_back()"<<endl;
    vec_name3.push_back(4);
    vec_name3.push_back(5);
    coutall(vec_name3);
    
    cout<<"尾部删除元素 pop_back()"<<endl;
    vec_name3.pop_back();
    coutall(vec_name3);
    
    
    //任意位置插入元素 insert函数
    vec_name3.insert(vec_name3.begin()+1,10); //第一个元素前插入元素,值为10
    vec_name3.insert(vec_name3.begin()+1,10); //第一个元素前插入元素,值为10
     //删除指定元素
    vec_name3.erase(vec_name3.begin()+1); //删除第1个元素
    vec_name3.erase(vec_name3.end()-1); //删除最后一个元素
     vec_name3.erase(vec_name3.begin()+2,vec_name3.end()-2); //删除区间[i,j];
    
    coutall(vec_name3);
    
    //注意:关于vector的下标操作。vector的下标操作只能改变或者获取已有的元素的值,不能往vector里添加元素!
    //使用下标改变元素的值和获取,但是此方法不会判断是否越界,因此尽量使用迭代器或者at(),
    vec_name3[0] = 20;
    for(int i=0;i<vec_name3.size();i++)
    {
        cout<<vec_name3[i]<<" ";
    }        
    cout<<endl<<vec_name3.at(1)<<endl;
    
    cout<<"返回第一个元素 front"<<endl;
    cout<<vec_name3.front()<<endl;
    
    cout<<"返回最后一个元素 back"<<endl;
    cout<<vec_name3.back()<<endl;
    
    
    
    //常用函数,元素排序
    sort(vec_name3.begin(),vec_name3.end());
    coutall(vec_name3);
    //元素查找,find(),求迭代器之间的距离 distance()
    vector<int>::iterator result = find(vec_name3.begin(),vec_name3.end(),10);
    if(result == vec_name3.end())
    {
        cout << "没找到"<<endl;
    }
    else
    {
        cout << "存在此元素,元素位数为"<<distance(vec_name3.begin(),result)<<endl;
    }
    //反转容器
    reverse(vec_name3.begin(),vec_name3.end());
    coutall(vec_name3);
    //交换元素或交换容器,交换容器是整个容器的元素,可用空间全部交换。
    swap(vec_name3[0],vec_name3[1]);
    coutall(vec_name3);
    cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
    cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
    
    
    coutall(vec_name6);
    cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
    cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
    
    swap(vec_name3,vec_name6);
    
    cout<<"-------after swap-----"<<endl;
    
    coutall(vec_name3);
    cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
    cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
    
    
    coutall(vec_name6);
    cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
    cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
      
    //清除容器 clear只是清除元素,但是空间没有释放。
    vec_name6.clear();
    coutall(vec_name6);
    cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
    cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
        
    cout<<"第一种方式,定义一个空容器,和之前容器swap,那么原本有数据有空间的容器就清空了。"<<endl;
    vector<int>().swap(vec_name6);
    
    cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
    cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
        
    cout<<"第二种方式,先clear,再使用shrink_to_fit()"<<endl;
    coutall(vec_name3);
    vec_name3.clear();
    vec_name3.shrink_to_fit();
    cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
    cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;    
    
    cout<<endl<<"STL VECTOR TEST END!\n";
    
    return 0;    
}
上一篇:如何在Oracle下创建自动递增字段


下一篇:Oracle笔记 五、创建表、约束、视图、索引、序列、同义词、表空间