【STL】序列式容器:vector

发布时间:2017-4-25 6:54:02 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"【STL】序列式容器:vector",主要涉及到【STL】序列式容器:vector方面的内容,对于【STL】序列式容器:vector感兴趣的同学可以参考一下。

先简单的说下序列式容器,该类容器是有序群集,其中每个元素均有固定的位置——取决于插入时间和地点,和元素值无关。换言之,就是容器中的元素位置取决于你插入该元素的时间或(和)往哪个位置插入。比如有的容器提供尾端追加元素函数,有的容器还提供向某位置插入某元素。STL 提供三个定义好的序列式容器:vector,deque,list。这里学习vector。 vector 将其元素置于一个动态数组中加以管理,与 array 非常类似,两者的唯一差别在于空间运用的灵活性,array 是静态空间,一旦配置了就不能更改,当需要容纳更多的元素时(此时已越界),需要重新手动配置更大的 array 空间,然后重新置入数据。而 vector 是动态空间,在同样的情况下,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。vector 同 array 一样可以很方便的通过索引值直接存取任何一个元素,在数组的尾端追加或移除元素均非常快速(当追加元素超出原有分配空间时,vector需要重新分配空间),但在其中间或头部插入移除元素就比较费时,需要移动安插点之后的所有元素以保持原来的相对位置。 这里通过程序介绍 vector 容器部分常见函数接口,先不涉及迭代器 #include <iostream> #include <vector> using namespace std; int main() { vector<int> coll, voll; for (int i = 0; i < 5; ++i) { coll.push_back(i); //尾端追加元素 } for (unsigned int i = 0; i < coll.size(); ++i) cout << coll[i] << endl; coll.pop_back(); //移除尾端元素 cout << "assign:" << endl; coll.assign(10, 10); //清空vector,插入10个值为10的元素 //别忘了,vector空间应用的灵活性,所以赋值个数大于之前元素个数是没问题的 for (unsigned int i = 0; i < coll.size(); ++i) cout << coll[i] << endl; coll.at(2) = 20; //返回指定位置的元素值的引用,做下标检查,可作左值 cout << coll.at(2) << endl; cout << endl; cout << coll.size() << endl; //容器当前实际元素数量 cout << coll.max_size() << endl; //容器所能容纳的最大元素数量 cout << coll.capacity() << endl; //容器实际能够容纳的元素数量 cout << "swap:" << endl; coll.swap(voll); //交换两个vector中的元素,容量也互换。所以swap()可用来缩减vector容量 for (unsigned int i = 0; i < voll.size(); ++i) cout << voll[i] << endl; cout << "clear:" << endl; coll.clear(); //清空vector cout << coll.size() << endl; //output:0 cout << coll.capacity() << endl; //output:0 coll.reserve(30); //预留至少可容纳30个元素的空间 cout << coll.capacity() << endl; return 0; } 引入迭代器,迭代器是一个“可遍历STL 容器内全部或部分元素”的对象。一个迭代器用来指出容器中的一个特定位置。迭代器是个所谓的 smart pointers,具有遍历复杂数据结构的能力。运用 start,finish,end_of_storage 三个迭代器便可轻易操作vector 容器。 //from STL source code v3.3 为便于理解,做了适当修改 iterator start; //表示目前使用空间的头 iterator finish; //表示目前使用空间的尾 iterator end_of_storage; //表示目前可用空间的尾所有容器类别都提供有一些成员函数,使我们得以获得迭代器并以之遍访所有元素,其中最为重要的是: begin() : 返回一个迭代器,指向容器起始点,// return start; end()  :返回一个迭代器,指向容器结束点。结束点在最后一个元素之后。所以容器的实际区间为 [ begin(), end() ),这只是表达一个概念,链式存储时元素就不是这样区间表示;// return finish; int main() { vector<int> coll; vector<int>::iterator pos, pos_1, pos_2, pos_3; //vector迭代器由实作版本定义,或许并不是一般指针 for (int i = 0; i < 5; ++i) { coll.push_back(i); } for (pos = coll.begin(); pos != coll.end(); ++pos) cout << *pos << endl; cout << "insert:" << endl; pos = coll.begin(); pos_1 = coll.insert(pos, 10); //在pos位置插入一个元素,并返回其迭代器, //运行后,*pos = 10; *pos_1 = 10; 容器元素:10 0 1 2 3 4 cout << "erase:" << endl; pos_2 = coll.erase(pos_1); //删除pos_1所指的元素,并返回下一元素迭代器 //运行后,*pos = 0, *pos_1 = 0, *pos_2 = 0 pos_3 = coll.erase(coll.begin() + 1, coll.end() - 1); //删除指定区间中的元素,半开半闭区间 for (pos = coll.begin(); pos != coll.end(); ++pos) cout << *pos << endl; //易知,clear()等价于erase(begin(), end()),其实就是 cout << coll.front() << endl; //返回第一个元素的引用 cout << coll.back() << endl; //返回最后一个元素的引用 return 0; }C++支持函数重载,上面只是部分函数,具体可参考《C++标准程序库》(侯捷译) 从上可知,安插和删除元素,都会使“作用点”之后的各元素的引用,指针,迭代器“失效”,这里的“失效”是说安插或删除之后的引用、指针以及迭代器关联的元素不再是操作之前的那个元素,因为迭代器关联的是容器中的位置,而不是针对某一特定元素,另外,安插元素可能会是引用指针和迭代器真正失效(容量不够时,安插会导致vector重新分配空间,),而删除不会,关联位置不变。 需要清楚的是,引用,指针以及迭代器关联均是容器中的位置,表示引用或指向容器空间中某位置的元素。为什么强调是容器空间中呢。因为容器构造完成后,容器也就配置了对应的空间,开辟了某片内存区域(空间并不等于内存),初始化迭代器之后,那么迭代器就关联了这块区域的某个位置(你可以运算迭代器改变其关联位置,但是无论怎么运算,其迭代器的合理有效区域均在容器配置的空间内)。一旦安插元素容器容量不够时,容器便会重新配置空间(先配置新空间,再复制旧空间数据,然后销毁旧空间),这时的空间在内存中的位置便不是原来的位置了,自然而然的,迭代器关联的位置也就不是在容器内了,就失效了。 现在的C++标准程序库保证 vector 的元素必须分布于连续空间中。 运用vector 时必须确保vector 的大小足以容纳所有数据,下面这个程序有点意思 int main() {     vector<char> coll;          for (int i = 0; i < 11; ++i)      //i<5时,程序异常出错(内存)         coll.push_back('a');     strcpy_s(&coll[0], 12, "hello,world");   //12     //i<5时,coll.assign(12, 'b');不会出错     cout << coll.size() << endl;             //output:11   当for循环中i<5时,output:5     cout << coll.capacity() << endl;         //output:13              output:6(6 < 12)     return 0; }这可能就是空间与内存的区别了吧,只有当容器的 capacity 足够容纳所有数据时,才不会抛出异常。strcpy_s 涉及到内存,并不通过容器的空间配置,而是直接拷贝数据到容器起始地址的一段内存中。 注意,千万不要把迭代器当做一个元素的地址来传递。vector 迭代器是由实作版本定义的,也许并不是个一般指针。 printf("%p\n", coll.begin()); //ERROR (可能会工作,但是是不可移植的) printf("%p\n", &coll[0]); //OK在VS2013下运行正常,但结果不一样。后面那个才是该元素的真正地址。 其内部机制的实现参见博文详解 vector 内部机制

上一篇:STL之iterator
下一篇:快捷键大全

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款