【STL】【容器】vector

一、vector的概念

vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。和string对象一样,标准库负责管理存储元素的相关内存。我们把vector称为容器,是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。使用vector之前,必须包含相应的头文件。


#include<vector>

usingstd::vector;

vector是一个类模板(class template),这个类和函数定义可用于不同的数据类型上。因此,我们可以定义保存string对象的vector,或保存int值的vector,又或是保存自定义的类类型对象(如Sales_item对象)的vector。声明从类模板产生的某种类型的对象,需要提供附加信息,信息的种类取决于模板。以vector为例,必须说明vector保存何种对象的类型,通过将类型放在类模板名称后面的尖括号中来指定类型:

 vector<int>ivec;

vector<Sales_item>Sales_vec;

和其他变量定义一样,定义vector对象要指定类型和一个变量的列表。上面的第一个定义,类型是vector,该类型即是含有若干int类型对象的vector,变量名为ivec。第二个定义的变量名是Sales_vec,它所保存的元素是Sales_item类型的对象。

二、vector的基本操作

1)vector对象的定义和初始化

vector类定义了好几种构造函数,用来定义和初始化vector对象。如下示出几种初始化vector对象的方式:

初始化的方式作用
vector< T >v1;vector保存类型为T的对象。默认构造函数v1为空。
vector< T>v2(v1);v2是v1的一个副本。
vector< T>v3(n,i);v3包含n个值为i的元素
vector< T>v4(n);v4含有值初始化的元素的n个副本
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main()
{
    vector<int> v1;             //v1保存的是类型为int的对象,v1为空
    cout<<v1.empty()<<"\n";     //v1为空打印1

    vector<int> v2(v1);         //通过v1拷贝v2
    cout<<v2.size()<<"\n";      //大小为0字节

    vector<float> v3(3,10.1f);   //v3包含3值为10.1f的元素
    vector<float>::iterator itv3 = v3.begin();     //创建一个迭代器对象赋值为v3.begin这个迭代器
    while(itv3 != v3.end())      //打印v3中的元素
    {
        cout<<*itv3<<" ";
        ++itv3;
    }

    cout<<"\n";
    vector<int> v4(3);
    for(int i=0; i<v4.size(); i++)
    {
        cout<<v4[i]<<" ";
    }
    cout<<"\n";
    return 0;
}
关键概念:vector对象动态增长

vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效地添加元素。因为vector增长的效率高,在元素值已知的情况下,最好是动态地添加元素。

虽然可以对给定元素个数的vector对象预先分配内存,但更有效的方法是先初始化一个空vector对象,然后再动态地增加元素。

a、值初始化

如果没有给出元素的初始化式,那么标准库将提供一个值初始化的(valueinitialized)元素初始化式。这个由库生成的初始值用于初始化容器中的每个元素。而元素初始化式的值取决于存储在vector中元素的数据类型。

如果vector保存内置类型(如int类型)的元素,那么标准库将用0值创建元素初始化值:

vector< int>fvec(10);

如果向量保存类类型(如string)的元素,标准库将用该类型的默认构造函数创建元素初始值:

vector< string>svec(10);
c、vector的操作
函数功能
empty()如果 v 为空,则返回 true, 否则返回 false 。
v . size ()返回 v 中元素的个数。
v . push _ back ( t )在 v 的末尾增加一个值为 t 的元素。
v [ n ]返回 v 中位置为 n 的元素。
v1 = v2把 v1 的元素替换为 v2 中元素的副本。
v1 == v2如果 v1 与 v2 相等,则返回 true 。
!=, <, <=, >, >=保持这些操作符惯有的含义。

(1)vector对象的size

empty和size操作类似于string类型的相关操作。成员函数size返回相应vector类定义的size_type的值。

使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型:

vector< int>::size_type//ok

vector::size_type//error

vector<int> v5(3,4);
vector<int>::size_type size = v5.size();
cout<<size<<endl;

(2)向vector添加元素

push_back()操作接受一个元素值,并将它作为一个新的元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”:

 //read words from the standard input and store the elements in a vector

stringword;

vector<string>text;//emptyvector

while(cin>>word){

text.push_back(word);

}           

该循环从标准输入读取一系列string对象,逐一追加到vector对象的后面。首先定义一个空的vector对象text。每循环一次就添加一个新元素到vector对象,并将从输入读取的word值赋予该元素。当循环结束时,text就包含了所有读入的元素。
循环停不下来

(3)vector的下标操作

vector中的对象是没有命名的,可以按vector中对象的位置来访问它们。通常使用下标操作符来获取元素。vector的下标操作类似于string类型的下标操作。

vector的下标操作符接受一个值,并返回vector中该对应位置的元素。vector元素的位置从0开始。下例使用for循环把vector中的每个元素值都重置为0:

    vector<int> v6(3,5);
    for(vector<int>::size_type ix = 0; ix != v6.size(); ++ix)
    {
        v6[ix] = 0;
    }

和string类型的下标操作符一样,vector下标操作的结果为左值,因此可以像循环体中所做的那样实现写入。另外,和string对象的下标操作类似,这里用size_type类型作为vector下标的类型。

在上例中,即使ivec为空,for循环也会正确执行。ivec为空则调用size返回0,并且for中的测试比较ix和0。第一次循环时,由于ix本身就是0,则条件测试失败,for循环体一次也不执行。

关键概念:安全的泛型编程

C++程序员习惯于优先选用!=而不是<来编写循环判断条件。

(4)下标操作不添加元素

初学C++的程序员可能会认为vector的下标操作可以添加元素,其实不然:

 vector<int>ivec; //emptyvector

for(vector<int>::size_type ix=0; ix!=10; ++ix)

ivec[ix]=ix;  //disaster:ivec has no elements

上述程序试图在ivec中插入10个新元素,元素值依次为0到9的整数。但是,这里ivec是空的vector对象,而且下标只能用于获取已存在的元素。

这个循环的正确写法应该是:

 for(vector<int>::size_typeix=0;ix!=10;++ix)

ivec.push_back(ix);//ok:adds new element with value ix

必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素

警告:仅能对确知已存在的元素进行下标操作
对于下标操作符([]操作符)的使用有一点非常重要,就是仅能提取确实已存在的元素,例如:

 vector<int>ivec;//empty vector

cout<<ivec[0];//Error: ivec has no elements!

vector<int>ivec2(10);//vector with 10 elements

cout<<ivec[10];//Error:ivec has elements 0...9

试图获取不存在的元素必然产生运行时错误。

附:常用方法

1.push_back() 在数组的最后添加一个数据

2.pop_back() 去掉数组的最后一个数据

3.at() 得到编号位置的数据

4.begin() 得到数组头的指针

5.end() 得到数组的最后一个单元+1的指针

6.front() 得到数组头的引用

7.back() 得到数组的最后一个单元的引用

8.max_size() 得到vector最大可以是多大

9.capacity() 当前vector分配的大小

10.size() 当前使用数据的大小

11.resize() 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值

12.reserve() 改变当前vecotr所分配空间的大小

13.erase() 删除指针指向的数据项

14.clear() 清空当前的vector

15.rbegin() 将vector反转后的开始指针返回(其实就是原来的end-1)

16.rend() 将vector反转构的结束指针返回(其实就是原来的begin-1)

17.empty() 判断vector是否为空

18.swap() 与另一个vector交换数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值