文章目录
标准vector表示对象的集合,其中所有的对象的类型都相同。集合中的每个对象都有一个与之相对应的索引,索引用于访问对象。因为vector"容纳着"其他的对象,所以它也常常被称作 容器,现在先对其进行简单介绍。
要想使用vector,必须包含其头文件#include<vector>
C++语言既有类模板,也有函数模板,其中vector是一个类模板,只有对于C++有深入的了解才能写出模板。
以vector为例子,提供额外的信息是vector内所存储的对象的类型:
vector<int> ivec;//1
vector<Sales_item> Sales_vec;//2
vector<vector<string>> files;//3
- ivec保存的是int类型的对象
- Sales_vec保存的是Sales_item的对象
- 该向量的元素是vector对象
vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,如vector<int>
PS:vector可以容纳绝大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含的vector。
PS:有些编译器仍然采用老式的用法,在编写以vector为元素的vector容器的时候,需要加一个空格,如:
vector<vecto<vector> > files;
定义和初始化vector对象
与任何一种类型相同,vector模板那控制着定义和初始化向量的方法下面将列出来:
vector<T> v1//1
vector<T> v2 = v1//2
vector<T> v3(n,val)//3
vector<T> v4(n)//4
vector<T> v5{a,b,c…}//5
vector<T> v6 = {a,b,c…}//6
- v1是一个空的容器,潜在存储的类型是T类型
- v2中包含由v1中所有元素的副本等效于v2(v1)
- v3中包含了n个重复的val值
- v4中包含了n个默认值(一般为0)
- v5中包含了n个元素,分别是a,b,c…
- v6等效于v5
还有就是在拷贝容器的时候,也需要注意的是两个容器的类型应当相同
列表初始化vector对象
C++11新标准提供了一个新的列表初始化的方式来进行初始化vector对象
例如:
vector<string> articles = {“a”,“an”,“the”};//1
vector<string> articles = (“a”,“an”,“the”);//2
- 正确
- 错误
这里介绍一下该初始化的规则:
- 使用拷贝初始化的时候,只能提供一个初始值。
- 如果提供的是一个类内的初始值,则只能使用拷贝初始化,或者使用花括号的形式进行初始化。
- 如果提供的是初始化列表,则只能把初始值都放在花括号里面进行列表初始化,而不能放在圆括号里面。
创建指定数量的元素
vector<T> v3(n,val)
vector<T> v4(n)
见上就行,也没什么分析的。
值初始化
如果vector对象的元素是内置类型,比如int,则元素的初始值自动设为0,如果元素是某种类型,比如string,则元素由该类的默认初始话决定。
vector<T> v4(n)
而对于此种初始化有着两个特殊的限制:
第一:有些类型要求必须明确提供初始值,如果vector对象中元素的类型不支持默认初始化,我们就必须提供初始化的元素值。
第二:如果只提供了元素的数量,而没有设定初始值,只能使用直接初始化。
列表初始值还是元素的数量?
某些情况下,初始化的真实含义依赖于传递初始值的是花括号还是圆括号,例如:用一个整数来初始化vector<int >的时候,整数的含义可能是vector对象的容量也可能是元素的值。类似的,用两个整数来初始化vector<int>,这两个整数可能是一个元素初始值。通过使用花括号和圆括号可以区别上述的区别:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v1(10);//1
vector<int> v2{ 10 };//2
vector<int> v1(10,1);//3
vector<int> v1{ 10,1 };//4
return 0;
}
- v1当中有10个元素,都是0。
- v2中只有1个元素10。
- v3中由10个元素,都是1。
- v4中有2个元素,10和1。
这里浅讲一下花括号和圆括号的区别:
如果使用的是圆括号,可以说是在构造vector对象。
如果是在使用花括号,表示我们正在使用列表初始化该vector对象,也就是说初始化过程中,会把花括号当中的数据当作元素进行使用,只有在无法执行初始化列表的时候才会考虑其他的初始化方式。
但在这里还有一个易错点就是,这里的列表初始化仅仅只是优先如果内部的值无法进行初始化,他还是会调用默认初始化的方式进行运行的。
#include<iostream>
#include<string>
#include<cctype>
#include<vector>
using namespace std;
int main()
{
vector<string> v5{ "hi" };//1
vector<stirng> v6("hi");//2
vector<string> v7(10);//3
vector<string> v8{ 10,"hi" };//4
return 0;
}
- 列表初始化,不介绍
- 错误,调用初始化函数错误
- 10个空string类型
- 虽然是花括号,但这里的运行,改变成了圆括号的使用。
向vector对象中添加元素
对于vector对象来说,直接初始化的方式使用于三种情况:初始值已知且数量较少,初始值是另一个vector对象的副本,所有的元素的初始值都一样。但是常见的情况却是相反的,所以便需要用到一个函数push_back向其中添加元素。push_back负责把一个值当成vector对象的尾元素压入vector的尾端
例如
#include<vector>
using namespace std;
int main()
{
string word;
vector<string> text;
while (cin>>word)
{
text.push_back(word);
}
cout << "结束" << endl;
return 0;
}
还有就是建议是:开始的时候创建空的vector对象,在运行的时候再动态添加元素。
向vector对象添加元素蕴含的编程假定
如果循环体内包含着有向vector对象添加元素的语句,则不能使用规范的for循环,具体可以见之后专门for的区域进行分析。
其他的vector操作
除了push_back以外,vector还提供了几种操作,大多数都和string的相关操作类似。
v.empty()//1
v.size()//2
v.push_back(t)//3
v[n]//4
v1=v2//5
v1={a,b,c…}//6
v1==v2//7
v1!=v2//8
<、<=、>、>=//9
- 如果v不含有任何元素,则返回true,否则返回false
- 返回v中元素的个数
- 向v的尾端添加一个为t的元素
- 返回v中第n个位置上的元素的引用
- 用v2中的元素拷贝替换v1中的元素
- 用列表中的元素拷贝替换v1中的元素
- v1和v2相等当且仅当他们的元素数量相同且对应位置的元素值都相同
- 与上面相反
- 顾名思义,按字典顺序比较
访问vector当中的元素与string对象中的字符方法差不多,也是通过元素再vector对象中的位置。
例如:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v1{ 1,2,3,4,5,6,7,8,9 };
for (auto& i : v1)//这里注意是引用
i *= i;
for (auto i : v1)
cout << i << " ";
cout << endl;
return 0;
}
这里有一个比较细节的东西就是需要使用引用类型,如果不使用引用类型,就仅仅只是i=容器中的值,改成引用后才可以修改容器当中的数据。
而对于vector的empty和size两个成员与string的同名成员的功能完全一致,但是在使用对应的size_type的时候也需要指明是谁定义的size_type,比如vector<int>::size_type.而非vector::size_type。
而其他的相同函数也不再赘述,读者可翻阅之前的本专栏的上一篇进行了解
计算vector内对象的索引
使用下标运算符能获取收到指定的元素。和string一样vector的对象下标也是从0开始,下标的类型是size_type类型的,只要vector的对象不是一个常量,就可以向下标运算符返回的元素赋值。简单举个例子:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<unsigned> score(11, 0);
unsigned grade;
while (cin>>grade)
{
if (grade <= 100)
++score[grade / 10];
}
return 0;
}
统计各分数段的学生个数,大家有兴趣可以调试一下。
不能使用下标的形式添加元素
顾名思义,当你想通过下标的形式添加元素的时候,你就会发现该位置是为空,根本没有对于区域进行添加,这也是新手很容易犯的错误。
本文详细介绍C++中的Vector容器,包括定义、初始化、添加元素及常用操作。解释如何使用列表初始化,探讨不同初始化方式的区别,并给出实用示例。

6272

被折叠的 条评论
为什么被折叠?



