C++标准库类型vector
来源:互联网 发布:数据比对公式vlookup 编辑:程序博客网 时间:2024/05/18 00:44
标准库类型vector表示对象的集合,集合中的每个对象都有一个与之对应的索引用于访问对象,所以常被称作容器(container)。使用如下声明以使用vector:
#include <vector>using std::vector;
C++既有类模板也有函数模板,vector是一个类模板。编译器根据模板创建类或者函数的过程称为实例化( instantiation),当使用模板时,需要指出编译器应把函数或者类实例化为何种类型。
对于类模板,需要提供一些额外信息,如下:
vector<int> ivec;vector<string> svec;vector<vector<string>> file;
vector能容纳绝大多数类型的对象作为其元素,但由于引用不是对象,所以不存在包含引用的vector,绝大多数内置类型或者类类型都可构成vector对象,甚至组成vector的元素也可以是vector。
早起版本的C++中,如果组成vector的元素还是vector或者其他模板类型,则其定义与C++11新标准有些不同。过去的定义方式必须在外层vector的右尖括号与其元素类型之间加一个空格,如:
vector<vector<string> > file;
定义和初始化
有如下几种方式定义和初始化vector:
vector<T> v1; //默认初始化,v1不含任何元素vector<T> v2(v1); //v2中包含v1中所有元素的副本vector<T> v2 = v1; //与上相同vector<T> v3(n, val); //包含n个重复的元素,每个元素的值都是valvector<T> v4(n); //包含了n个地执行了值初始化的对象vector<T> v5{a, b, c}; //列表初始化,包含了初始值个数的元素,每个元素被赋予相应的初始值vector<T> v6={a, b, c}; //与上相同
允许把一个vector对象拷贝给另外一个vector对象,此时,新vector对象的元素就是原vector对象对应元素的副本,但是两个vector对象的类型必须相同。
如果提供的是初始值元素的列表,则只能把初始值都放在花括号里面进行初始化,而不能放在圆括号里面:
vector<string> v1{"a", "bb", "ccc"}; //正确vector<string> v1("a", "bb", "ccc"); //错误
如果只提供元素数量而略去初始值,此时,库会创建一个值初始化的元素初值,并把它赋给容器中所有的元素。如vector对象的元素类型是内置类型,比如int则元素初始值自动设为0,如果是某种类类型,则元素由类默认初始化。如果vector对象中的元素的类型不支持默认初始化,就必须提供初始元素值,对于该种类型的对象来说,只提供元素数量而不设定初始值无法完成初始化工作。
某些情况下,初始化的真实含义依赖于传递初始值时用的是花括号还是圆括号。如:
vector<int> v1(10); //10个元素,每个元素都是0vector<int> v2{10}; //1个元素,值为10vector<int> v3(10, 1); //10个元素,每个元素都是1vector<int> v4{10, 1}; //2个元素,分别为10和1
如果使用圆括号,可以说提供的值是用来构造(construct)vector对象的。如果用的是花括号,可以表述为想要使用列表初始化(list initialize)该vector对象,即尽可能的把花括号内的值当成是元素初始值的列表来处理,只有在无法进行列表初始化是才会考虑其他初始化方式。
如果使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了。如:
vector<string> v1{"hi"}; //列表初始化vector<string> v2("hi"); //错误,不可使用字面值字符串构建vector对象vector<string> v3(10); //v3有10个默认初始化的元素vector<string> v4{10, "hi"}; //v4有10个值为"hi"的元素
确认无法使用列表初始化之后,编译器会尝试使用默认值初始化vector对象。
添加元素
可以使用push_back函数向vector中添加元素,该函数负责将一个值当成vector对象的尾元素压到vector对象的尾端,如:
vector<int> v2;for (int i = 0; i < 10; ++i) { v2.push_back(i);}
C++标准要求vector应该能在运行时高效快速的添加元素,在定义vector对象时设定其大小会使其性能更差,只有一种例外,即所有元素值都一样的情况。一旦元素的值有不同,更有效的方法是先定义一个空的vector对象,再在运行时添加具体值。
vector的使用有很多隐含的要求,如:
如果循环体内部包含有向vector对象添加元素的语句,则不能使用范围for循环。范围for循环不应改变其所遍历序列的大小。
其他操作
包括如下一些操作,大致与string的操作类似:
v.empty() //若v中不含任何元素则判断为真,否则为假v.size() //返回v中元素的个数v.push_back(t) //向v的末尾添加元素tv[n] //返回v中第n个位置上的元素的引用v1 = v2 //用v2中元素的拷贝替换v1中的元素v1 = {a,b,c...} //用列表中元素的拷贝替换v1中的元素v1 == v2 //当且仅当它们的元素数量相同且对应位置的元素值都相同时为真<,<=,>,>= //按字典序进行比较
访问vector中元素方法与访问string对象中字符的方法差不多,如:
vector<int> v{1,2,3,4,5,6,7,8,9};for (auto &i : v) { i += 10;}for (auto i : v) { cout << i << endl;}
vector的empty和size两个函数与string的同名成员功能完全一致,注意size返回vector中元素个数,返回值的类型是由vector定义的size_type类型,如:
vector<int>::size_type //正确vector::size_type //错误
要使用size_type需首先指定它是由哪种类型定义的,vector对象的类型总是包含这元素的类型。
关系运算符按照字典顺序进行比较:如果两个vector对象的容量不同,但是相应位置上的元素都一样,则元素较少的vector对象小于元素较多的vector对象;若元素的值有区别,则其大小关系由第一对相异的元素值的大小关系决定。只有当元素的值可以比较时,vector对象才能被比较。
使用下标运算符可以获取到指定的元素,但是不能使用下标形式来添加元素,string对象也是如此。只能对确定已知存在的元素进行下标操作,试图使用下标来访问一个不存在的元素将引发错误,不过这种错误不会被编译器发现,而是在运行时产生一个不可预知的值。缓冲区溢出(buffer overflow)指的就是这类错误。
- C++,标准库类型vector
- C++primer 3.3 标准库类型 vector
- 标准库vector类型
- 标准库vector类型
- 标准库vector类型
- 标准库vector类型
- 标准库Vector类型
- 标准库vector类型
- 标准库 vector 类型
- 标准库vector类型
- 标准库类型vector
- 标准库vector类型
- 标准库类型<vector>
- 标准库vector类型
- 标准库类型vector
- 标准库 vector 类型
- 标准库类型vector
- 标准库类型vector
- 主组织物料>物料目录>规格型号 无法更新解决方案
- Python学习笔记(13) -- (装饰器)
- CANVAS基础教程
- win7右下角无线标识显示打着红叉实际可以上网怎么解决?
- BTrace入门
- C++标准库类型vector
- Linux/UNIX 10个有用的Sar命令监控系统性能的例子
- Haskell学习笔记 --- 基础语法篇一
- 曾优雅击退史上最凶狠的DDoS攻击_AliGuard的高性能从何而来?
- 解决 Android N 7.0 上 报错:android.os.FileUriExposedException
- c++中reverse和resize的区别
- 采用Java阻塞IO对已经到达的socket流实现非阻塞完整读取(一个简单的java http server实现)
- mongodb配置及其开机自启动设置
- **kwargs 的用法