C++ STL中vector(向量容器)使用简单介绍
原文:http://www.seacha.com/article.php/knowledge/cbase/2013/0903/2205.html
C++ vector(向量容器)是一个线性顺序结构。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组,或者作为动态内存。
在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作:
首先,vector 会申请一块更大的内存块;
然后,将原来的数据拷贝到新的内存块中;
其次,销毁掉原内存块中的对象(调用对象的析构函数);
最后,将原来的内存空间释放掉。
如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。
vector 的特点:
(1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。即它可以像数组一样操作,并且可以进行动态操作。通常体现在push_back() pop_back() 。
(2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at()
(3) 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。
(4) 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。Vector 被设计成只能在后端进行追加和删除操作,其原因是vector 内部的实现是按照顺序表的原理。
(5) 只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop 。
(6) 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗性能。 所以要vector 达到最优的性能,最好在创建vector 时就指定其空间大小。
Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。
1.Constructors 构造函数
vector<int> v1; //构造一个空的vector
vector<int> v1( 5, 42 ); //构造了一个包含5个值为42的元素的Vector
2.Operators 对vector进行赋值或比较
C++ Vectors能够使用标准运算符: ==, !=, <=, >=, <, 和 >.
要访问vector中的某特定位置的元素可以使用 [] 操作符.
两个vectors被认为是相等的,如果:
1.它们具有相同的容量
2.所有相同位置的元素相等.
vectors之间大小的比较是按照词典规则.
3.assign() 对Vector中的元素赋值
语法:
// 将区间[start, end]的元素赋到当前vector
void assign( input_iterator start, input_iterator end );
// 赋num个值为val的元素到vector中,这个函数将会清除掉为vector赋值以前的内容。
void assign( size_type num, const TYPE &val );
4.at() 返回指定位置的元素
语法:
TYPE at( size_type loc );//差不多等同v[i];但比v[i]安全;
5.back() 返回最末一个元素
6.begin() 返回第一个元素的迭代器
7.capacity() 返回vector所能容纳的元素数量(在不重新分配内存的情况下)
8.clear() 清空所有元素
9.empty() 判断Vector是否为空(返回true时为空)
10.end() 返回最末元素的迭代器(译注:实指向最末元素的下一个位置)
11.erase() 删除指定元素
语法:
iterator erase( iterator loc );//删除loc处的元素
iterator erase( iterator start, iterator end );//删除start和end之间的元素
12.front() 返回第一个元素的引用
13.get_allocator() 返回vector的内存分配器
14.insert() 插入元素到Vector中
语法:
//在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器
iterator insert( iterator loc, const TYPE &val );
//在指定位置loc前插入num个值为val的元素
void insert( iterator loc, size_type num, const TYPE &val );
//在指定位置loc前插入区间[start, end]的所有元素
void insert( iterator loc, input_iterator start, input_iterator end );
15.max_size() 返回Vector所能容纳元素的最大数量(上限)
16.pop_back() 移除最后一个元素
17.push_back() 在Vector最后添加一个元素
18.rbegin() 返回Vector尾部的逆迭代器
19.rend() 返回Vector起始的逆迭代器
20.reserve() 设置Vector最小的元素容纳数量
//为当前vector预留至少共容纳size个元素的空间
21.resize() 改变Vector元素数量的大小
语法:
//改变当前vector的大小为size,且对新创建的元素赋值val
void resize( size_type size, TYPE val );
22.size() 返回Vector元素数量的大小
23.swap() 交换两个Vector
语法:
void swap( vector &from );
Vector用法 :
1.声明:
一个vector类似于一个动态的一维数组。
vector<int> a; //声明一个元素为int类型的vector a
vectot<MyType> a; //声明一个元素为MyType类型的vector a
这里的声明的a包含0个元素,既a.size()的值为0,但它是动态的,其大小会随着数据的插入和删除改变而改变。
vector<int> a(100, 0); //这里声明的是一个已经存放了100个0的整数vector
你可以用以下的几种方法声明一个 vector 对象:
vector<float> v(5, 3.25); //初始化有5 个元素,其值都是3.25
vector<float> v_new1(v);
vector<float> v_new2 = v;
vector<float> v_new3(v.begin(), v.end());
这四个vector 对象是相等的,可以用operator==来判断。
2.向量操作
常用函数:
size_t size(); // 返回vector的大小,即包含的元素个数
void pop_back(); // 删除vector末尾的元素,vector大小相应减一
void push_back(); //用于在vector的末尾添加元素
T back(); // 返回vector末尾的元素
void clear(); // 将vector清空,vector大小变为0
其他访问方式:
cout<<a[5]<<endl;
cout<<a.at(5)<<endl;
以上区别在于后者在访问越界时会抛出异常,而前者不会。
3.遍历
(1). for(vector<datatype>::iterator it=a.begin(); it!=a.end();it++)
cout<<*it<<endl;
(2). for(int i=0;i<a.size;i++)
cout<<a[i]<<endl;
现在想得到容器中能保存的最大元素数量就可以用 vector 类的成员函数max_size():
vector<shape>::size_type max_size = my_shapes.max_size();
当前容器的实际尺寸 --- 已有的元素个数用size():
vector<shape>::size_type size = my_shapes.size();
就像size_type 描述了vector 尺寸的类型,value_type 说明了其中保存的对象的类型:
cout << "value type: " << typeid(vector<float>::value_type).name();
输出:
value type: float
可以用capacity()来取得vector 中已分配内存的元素个数:
vector<int> v;
vector<int>::size_type capacity = v.capacity();
vector 类似于数组,可以使用下标[]访问:
vector<int> v(10);
v[0] = 101;
注意到这里预先给10 个元素分配了空间。你也可以使用vector 提供的插入函数来动态的扩展容器。成员函数push_back()就在vector 的尾部添加了一个元素:
v.push_back(3);
也可以用insert()函数完成同样的工作:
v.insert(v.end(), 3);
这里insert()成员函数需要两个参数:一个指向容器中指定位置的迭代器(iterator),一个待插
入的元素。insert()将元素插入到迭代器指定元素之前。
现在对迭代器(Iterator)做点解释。Iterator 是指针(pointer)的泛化,iterator 要求定义
operator*,它返回指定类型的值。Iterator 常常和容器联系在一起。例子:
vector<int> v(3);
v[0] = 5;
v[1] = 2;
v[2] = 7;
vector<int>::iterator first = v.begin();
vector<int>::iterator last = v.end();
while (first != last)
cout << *first++ << " ";
上面代码的输出是:
5 2 7
begin()返回的是vector 中第一个元素的iterator,而end()返回的并不是最后一个元素的
iterator,而是past the last element。在STL 中叫past-the-end iterator。
4.作为动态内存使用
vector<unsigned char> vecData;
vecData.resize(2000);
unsigned char *data = (unsigned char *)&_vecData[0];
if (2000 <= datalen + new_datalen)
{
vecData.reserve(datalen + new_datalen); // 或者增加一个指定大小的数据。
}
vecData.insert(_vecData.end(), (unsigned char)buf[0], rc);
cout << "data: " << data << endl;
(责任编辑:admin) |
C++ STL中vector(向量容器)使用简单介绍的更多相关文章
- C++STL之vector向量容器
vector向量容器 vector向量容器不但能向数组一样对元素进行随机访问, 还能在尾部插入元素 vector具有内存自动管理的功能, 对于元素的插入和删除, 可动态调整所占的内存空间 vect ...
- Cocos2d-x中Vector<T>容器以及实例介绍
Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容纳的是Ref及子类所创建的对象指针,其中的T是模板,表示能够放入到容器中的类型,在Cocos2d-x 3.x中T ...
- C++的STL中vector内存分配方法的简单探索
STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux CentOS 5.2 1.代码 #include <vector> #include <stdio ...
- STL中vector、list、deque和map的区别
1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...
- 【转】STL中vector、list、deque和map的区别
1.vector 向量 相当于一个数组 在内存中分配一块连续的内容空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数 ...
- stl中顺序性容器,关联容器两者粗略解释
什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...
- vector向量容器(常用的使用方法总结)
关于STL中vector容器的学习,编译运行后边看代码,边看执行结果效果更佳,还是想说看别人的代码一百遍,不如自己动手写一遍. vector向量容器不但能像数组一样对元素进行随机访问,还能随时在尾部插 ...
- 标准模板库使用参考——vector向量容器
C++的STL从广义上讲分为algorithm(算法),container(容器)和iterator(迭代器)三类,包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法. 在C++标准库中,ST ...
- 学习笔记之vector向量容器
今天复习到vector向量容器,里面包括vector向量容器的一些优点以及具体的使用方法及代码,分享给大家. Vector向量容器不但能够像数组一样对元素进行随机访问,还可以在尾部插入元素,是一种简单 ...
- STL中的set容器的一点总结
1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...
随机推荐
- Linux修改/etc/profile不生效的问题
今天在原来的机器上修改了JDK的路径配置,但死活不生效. 后来查了~/.bash_profile文件,里面没有配置. 最后查~/.bashrc文件,发现里面有JDK的配置
- TODO Auto-generated method stub
在 菜单栏中 Window --> Preferences -->Java -->Code Style -->Code Templates--> Code --> ...
- .NET 环境中使用RabbitMQ(转)
在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方,比如发送短信 ...
- C#编写的通过汉字得到拼音和五笔码
public static class SpellAndWbConfig { #region 变量声明 // XML文件读取实例 /// <summary> /// XML文件读取实例 / ...
- 將後台的Json數據返回到前台
前台JS代碼 $.post('/Book/GetBookClassIDByName', { BookName: "旅遊手冊" }, function (data) { if (da ...
- 《深入理解Nginx》阅读与实践(三):使用upstream和subrequest访问第三方服务
本文是对陶辉<深入理解Nginx>第5章内容的梳理以及实现,代码和注释基本出自此书. 一.upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例 (一)模块框 ...
- .net正则表达式
1. "^-?[1-9]\\d*$",//整数 2. "^[1-9]\\d*$", //正整数 3. intege2:"^-[1-9]\\d*$&qu ...
- jqeury 合并单元格
function mergeCells() { var tbodyTlth = $("#datatable_ajax1 tbody").find("tr").l ...
- 循序渐进Python3(七) --1-- 面向对象
Python 面向对象 什么是面向对象编程? 面向对象编程是一种程序设计范式 对现实世界建立对象模型 把程序看作不同对象的相互调用 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Py ...
- jQuery下拉框插件8种效果
jQuery自定义漂亮的下拉框插件8种效果 jquery美化选择器实例有:边框.下划线. 伸缩 .滑动. 覆盖. 旋转. 弹出层选择 .环形效果. 在线预览 <body class=" ...