




免费预览已结束,剩余34页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+标准库介绍标准库里有什么呢,同C标准库最大的不同应该是STL。有了STL,不必再写大多的标准数据结构和算法,并且可获得非常高的性能。Stl中有几个基本的概念:容器:可容纳各种数据类型的数据结构。迭代器:可依次存取容器中数据的结构算法:通过迭代器对容器进行某种操作的函数举个容易理解的例子:数组就是个容器,而指针就是迭代器。接下来将用几小节专门描述stl的概貌。下面所提到的内容多取自C+ 标准程序库一书,以下将不另行说明。41 stl中的容器标准容器有7种,不同实现有相应的扩充。7种容器对应的模型如下:vector 其中箭头表示数据增长方向。实际上就是个动态数组。在尾端增删元素具有较佳的性能。Deque在两端增删元素具有较佳的性能。List 双向链表,在任何位置增删元素都具有相近的性能。上述三种容器称为序列式容器(sequence container)。元素的插入位置同元素的值无关。Set/Multiset:此种容器内的元素是已序的,插入任何元素,都按相应的排序准则来确定其位置。Set中不允许相同元素,multiset中允许存在相同的元素。Map/Multimap:Map同Multimap的不同在于是否允许相同的元素。Map与Set的不同在于Map中存放的是成对的key/value。并根据key对元素进行排序。上述四种容器称为关联式容器(Associative Container)。特点是在查找时具有非常好的性能。以上述7种容器为基础,stl还实现了Stacks,Queues,Priority Queues。用Map来举个例子:typedef map mapforaccount;/定义mapforaccount lunch;/赋值lunch“陈勇”50.00;lunch“林立坚”35.00;lunch“陈阵”45.00;lunch“czzs”=65.00;/打印mapforaccount:iterator pos;for(pos=lunch.begin();pos!=lunch.end();+pos) cout“姓名:”first”t” ”余额:”secondendl;上述各种容器都有一些成员函数,支持一些基本的操作和对某些算法进行优化。不同的容器的成员函数并不完全相同。其中:n 所有容器都支持以下操作符:,!,,=。当且仅当两个容器类型相同,元素数目相同,元素顺序相同,并每个元素都相等时为true。小于的情况以字典序进行判定。n insert(),push_front(),push_back()等添加成员得函数n remove(),pop_front(),pop_back(),at()等删除及读取元素的函数。总之这些函数使你对容器中元素得读写更为方便。剩下得成员函数,诸如sort(),merge()等是容器根据本身特性对某些算法得优化,实现与下面所讲得算法相同得功能。可作为动态数组的vector 非常的常用,以他为例来看一下容器都可以为我们做些什么。构造与析构vector c产生一个空vectorvector c1(c2)生成一个c2的副本vector c(n)产生一大小为n的容器,用缺省构造函数生成其中每个元素的值vector c(n,elem)产生一大小为n的容器,其中每个元素的值都是elemvector c(beg,end)产生一个以beg,end区间为初值的vectorc.vector()销毁所有元素,并释放内存非变动性操作c.size()返回容器中元素的数量c.empty()大小是否为0c.max_size()可容纳元素的最大数量capacity()重新分配空间前所能容纳的元素的最大数量reserve()保留一定大小的空间c1=c2c1!=c2c1c2c1=c2赋值操作c1=c2将c2的元素全部复制给c1c.assign(n,elem)用n个元素填充cc.assign(beg,end)用指定区间的内容填充cc1.swap(c2)c1,c2的内容互换swap(c1,c2)同上为全局函数元素的存取c.atidx返回索引idx所表示的元素,检查边界cidx同上但不检查边界c.front()返回第一个元素,不检查其是否存在c.back()返回最后一个元素,不检查其是否存在迭代器相关函数c.begin()返回指向第一个元素的随机存取迭代器c.end()返回指向最后一个元素的随机存取迭代器c.rbegin()返回指向第一个元素的逆向迭代器c.rend()返回指向最后一个元素的逆向迭代器安插及移除操作c.insert(pos,elem)在pos位置插入一个新元素副本,并返回新元素位置c.insert(pos,n,elem)在pos位置插入n个新元素副本c.insert(pos,beg,end)在pos位置插入beg,end)区间内所有元素的副本c.push_back(elem)在尾部添加一个elemc.pop_back()移除最后一个元素,不回传c.erase(pos)移除pos位置的元素,返回下一元素的位置c.erase(beg,end)移除beg,end)区间内所有元素,并传回新位置c.resize(num)将元素数量改为numc.clear()移除所有元素看如下的程序段:这是为说明vector各个成员函数的使用而做的。typedef vector stringarray;/ PRINT_ELEMENTS负责输出容器中的所有元素template inline void PRINT_ELEMENTS(const T& coll, const char* cptcstr= ) typename T:const_iterator pos; cout cptcstr endl; for(pos=coll.begin();pos!=coll.end();+pos) cout *pos ; coutendl; int main() stringarray filename;/empty vector /在容器中的元素数量达到10之前不用重新分配内存 filename.reserve(10); filename.push_back(c:test1.emf); filename.push_back(c:test2.emf); filename.push_back(c:test3.emf); filename.push_back(c:test4.emf); filename.push_back(c:test5.emf); filename.push_back(c:test6.emf); PRINT_ELEMENTS(filename,After push_back:); cout max_size(): filename.max_size() endl; cout size(): filename.size() endl; cout capacity(): filename.capacity()endl;/在第一个元素的位置插入 filename.insert(filename.begin(),d:ie.emf); PRINT_ELEMENTS(filename,After insert:); cout Now the first element is: filename0 endl;/ back()返回最后一个元素 cout Now the last element is: filename.back() endl;/为tempfilename赋初值 stringarray tempfilename=filename; PRINT_ELEMENTS(tempfilename,Before erase:);/删除前三个元素 tempfilename.erase(tempfilename.begin(),tempfilename.begin()+3); PRINT_ELEMENTS(tempfilename,after erase:);/删除最后一个元素 tempfilename.pop_back(); PRINT_ELEMENTS(tempfilename,after pop_back():); /来个恐怖的,这个说明vector在内存中是连续存放的 vector v; v.resize(41); strcpy(&v0,this is a test); printf(%sn,&v0); return 0; 输出结果为:After push_back:c:test1.emf c:test2.emf c:test3.emf c:test4.emf c:test5.emf c:test6.emf max_size():357913941size():6capacity():10After insert:d:ie.emf c:test1.emf c:test2.emf c:test3.emf c:test4.emf c:test5.emf c:test6.emf Now the first element is: d:ie.emfNow the last element is: c:test6.emfBefore erase:d:ie.emf c:test1.emf c:test2.emf c:test3.emf c:test4.emf c:test5.emf c:test6.emf after erase:c:test3.emf c:test4.emf c:test5.emf c:test6.emf after pop_back():c:test3.emf c:test4.emf c:test5.emfthis is a test学习STLmap,STLset之数据结构基础作者:winter摘要:本文列出几个基本的STLmap和STLset的问题,通过解答这些问题讲解了STL关联容器内部的数据结构,最后提出了关于 UNIX/LINUX自带平衡二叉树库函数和map,set选择问题,并分析了map,set的优势之处。对于希望深入学习STL和希望了解 STLmap等关联容器底层数据结构的朋友来说,有一定的参考价值。STLmap和set的使用虽不复杂,但也有一些不易理解的地方,如:#为何map和set的插入删除效率比用其他序列容器高?#为何每次insert之后,以前保存的iterator不会失效?#为何map和set不能像vector一样有个reserve函数来预分配数据?#当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何?或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构。C+STL之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector,string,list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入、排序、删除、查找等。让用户在STL使用过程中,并不会感到陌生。C+STL中标准关联容器set,multiset,map,multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为 RB树(Red-BlackTree)。RB树的统计性能要好于一般的平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和 Landis,将其称为AVL-树),所以被STL选择作为了关联容器的内部结构。本文并不会介绍详细AVL树和RB树的实现以及他们的优劣,关于RB树 的详细实现参看红黑树:理论与实现(理论篇)。本文针对开始提出的几个问题的回答,来向大家简单介绍map和set的底层数据结构。为何map和set的插入删除效率比用其他序列容器高?大部分人说,很简单,因为对于关联容器来说,不需要做内存拷贝和内存移动。说对了,确实如此。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。结构图可能如下:A/BC/DEFG因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点就OK了。这里的一切操作就是指针换来换去,和内存移动没有关系。为何每次insert之后,以前保存的iterator不会失效?看见了上面答案的解释,你应该已经可以很容易解释这个问题。iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然 被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了 保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时 候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放 到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。为何map和set不能像vector一样有个reserve函数来预分配数据?我以前也这么问,究其原理来说时,引起它的原因在于在map和set内部存储的已经不是元素本身了,而是包含元素的节点。也就是说map内部使用的 Alloc并不是map声明的时候从参数中传入的Alloc。例如:mapint,int,less,Allocintmap;这时候在intmap中使用的allocator并不是Alloc,而是通过了转换的Alloc,具体转换的方法时在内部通过 Alloc:rebind重新定义了新的节点分配器,详细的实现参看彻底学习STL中的Allocator。其实你就记住一点, 在map和set内面的分配器已经发生了变化,reserve方法你就不要奢望了。当数据元素增多时(10000和20000个比较),map和set的插入和搜索速度变化如何?如果你知道log2的关系你应该就彻底了解这个答案。在map和set中查找是使用二分查找,也就是说,如果有16个元素,最多需要比较4次就能找到结 果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素呢?最多不过15次。 看见了吧,当数据量增大一倍的时候,搜索次数只不过多了1次,多了1/14的搜索时间而已。你明白这个道理后,就可以安心往里面放入元素了。最后,对于map和setWinter还要提的就是它们和一个c语言包装库的效率比较。在许多unix和linux平台下,都有一个库叫isc,里面就提供类似于以下声明的函数:voidtree_init(void*tree);void*tree_srch(void*tree,int(*compare)(),void*data);voidtree_add(void*tree,int(*compare)(),void*data,void(*del_uar)();inttree_delete(void*tree,int(*compare)(),void*data,void(*del_uar)();inttree_trav(void*tree,int(*trav_uar)();voidtree_mung(void*tree,void(*del_uar)();许多人认为直接使用这些函数会比STLmap速度快,因为STLmap中使用了许多模板什么的。其实不然,它们的区别并不在于算法,而在于内存碎片。 如果直接使用这些函数,你需要自己去new一些节点,当节点特别多,而且进行频繁的删除和插入的时候,内存碎片就会存在,而STL采用自己的 Allocator分配内存,以内存池的方式来管理这些内存,会大大减少内存碎片,从而会提升系统的整体性能。Winter在自己的系统中做过测试,把以 前所有直接用isc函数的代码替换成map,程序速度基本一致。当时间运行很长时间后(例如后台服务程序),map的优势就会体现出来。从另外一个方面 讲,使用map会大大降低你的编码难度,同时增加程序的可读性。何乐而不为?STL之map2006-07-26 13:191. map中的元素其实就是一个pair.2. map的键一般不能是指针, 比如int*, char*之类的, 会出错. 常用的就用string了,int也行.3. map是个无序的容器, 而vector之类是有序的. 所谓有序无序是指放入的元素并不是按一定顺序放进去的, 而是乱序, 随机存放的(被映射后近似随机存放).所以遍历的时候有些效率差别.4. 判断有没有找到该键的内容可以这样: std:map:const_iterator cIter;cIter = stdfile.m_map.find(s);if (cIter = stdfile.m_map.end()/ 没找到就是指向END了m_vecMoreFile.push_back(s);如果键的内容是指针的话, 应该用NULL指针也可以判断了.5. 遍历:std:map:iterator iter;for (iter = m_map.begin(); iter != m_map.end(); iter+)std:string s = iter-second.filename;由于map内容可以相当一个PAIR, 那就简单了, 用iter-second就可以取得值了.可顺便转个其它的几种用法: 1 头文件include 2 定义map my_Map;或者是typedef map MY_MAP;MY_MAP my_Map;3 插入数据(1) my_Mapa = 1;(2) my_Map.insert(map:value_type(b,2);(3) my_Map.insert(pair(c,3);(4) my_Map.insert(make_pair(d,4);4 查找数据和修改数据(1) int i = my_Mapa;my_Mapa = i;(2) MY_MAP:iterator my_Itr;my_Itr.find(b);int j = my_Itr-second;my_Itr-second = j;不过注意,键本身是不能被修改的,除非删除。5 删除数据(1) my_Map.erase(my_Itr);(2) my_Map.erase(c);还是注意,第一种情况在迭代期间是不能被删除的,道理和foreach时不能删除元素一样。6 迭代数据for (my_Itr=my_Map.begin(); my_Itr!=my_Map.end(); +my_Itr) 7 其它方法my_Map.size() 返回元素数目my_Map.empty() 判断是否为空my_Map.clear() 清空所有元素可以直接进行赋值和比较:=, , =, , =, != 等等 遍历:#include#include using namespace std;int main()mapM;M1=2;M2=3;map:iterator iter;for (iter = M.begin(); iter != M.end(); iter+)coutfirst secondendl;return 0;STL之map学习soarguy写于2006-4-13 19:10:00STL之map学习 在工作中遇到了很多STL的咚咚,真实汗颜,以前没有用过,所以不得不现学现卖了,:)。只要有了一点泛型编程的概念,看起资料来应该不成问题,此篇也仅限于初学者,高手莫进。STL也是一个博大精深的概念和范畴,以前基本上只是出现在C+中,随着Java 1.5和C# 2.0的引入,开始再次成为热点。推荐读物侯老的泛型编程与STL。本篇参考自C+ Standard Lib*y : A Tutorial and Reference。 map跟C#里面的Hashtable相似,都是提供一个键值对容器,只不过Hashtable封装的更好一些。map与multimap差别仅仅在于multiple允许一个键对应多个值。 1 头文件i nclude 2 定义map my_Map;或者是typedef map MY_MAP;MY_MAP my_Map;3 插入数据(1) my_Mapa = 1;(2) my_Map.insert(map:value_type(b,2);(3) my_Map.insert(pair(c,3);(4) my_Map.insert(make_pair(d,4);4 查找数据和修改数据(1) int i = my_Mapa; my_Mapa = i;(2) MY_MAP:iterator my_Itr; my_Itr.find(b); int j = my_Itr-second; my_Itr-second = j;不过注意,键本身是不能被修改的,除非删除。5 删除数据(1) my_Map.erase(my_Itr);(2) my_Map.erase(c);还是注意,第一种情况在迭代期间是不能被删除的,道理和foreach时不能删除元素一样。6 迭代数据for (my_Itr=my_Map.begin(); my_Itr!=my_Map.end(); +my_Itr) 7 其它方法my_Map.size() 返回元素数目my_Map.empty() 判断是否为空my_Map.clear() 清空所有元素可以直接进行赋值和比较:=, , =, , =, != 等等更高级的应用查帮助去吧,_标准模板库(STL)介绍(上)作者: winter 作者:Scott Field 本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂。不失为STL的入门文章,新手不容错过! 这篇文章是关于C+语言的一个新的扩展标准模板库的(Standard Template Library),也叫STL。 当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话题的深度和广度。有很多内容要含盖,也有很多详细描述STL的书。因此我重 新考虑了一下我原来的想法。我为什么要写这篇文章,又为什么要投稿呢?这会有什麽用呢?有再来一篇关于STL的文章的必要吗? 当我翻开Musser and Saini的页时,我看到了编程时代在我面前消融。我能看到深夜消失了, 目标软件工程出现了。我看到了可维护的代码。一年过去了,我使用STL写的软件仍然很容易维护。 让人吃惊的是其他人可以没有我而维护的很好! 然而,我也记得在一开始的时候很难弄懂那些技术术语。一次,我买了Musser&Saini,每件事都依次出现,但是在那以前我最渴望得到的东西是一些好的例子。 当我开始的时候,作为C+一部分的Stroustrup还没出来,它覆盖了STL。 因此我想写一篇关于一个STL程序员的真实生活的文章可能会有用。如果我手上有一些好的例子的话,特别是象这样的新题目,我会学的更快。 另外一件事是STL应该很好用。因此,理论上说,我们应该可以马上开始使用STL。 什麽是STL呢?STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list, vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。 STL的目的是标准化组件,这样你就不用重新开发它们了。你可以仅仅使用这些现成的组件。STL现在是C+的一部分,因此不用额外安装什麽。它被内建在 你的编译器之内。因为STL的list是一个简单的容器,所以我打算从它开始介绍STL如何使用。如果你懂得了这个概念,其他的就都没有问题了。另外, list容器是相当简单的,我们会看到这一点。 这篇文章中我们将会看到如何定义和初始化一个list,计算它的元素的数量,从一个list里查找元素,删除元素,和一些其他的操作。要作到这些,我们将会讨论两个不同的算法,STL通用算法都是可以操作不止一个容器的,而list的成员函数是list容器专有的操作。 这是三类主要的STL组件的简明纲要。STL容器可以保存对象,内建对象和类对象。它们会安全的保存对象,并定义我们能够操作的这个对象的接口。放在蛋架 上的鸡蛋不会滚到桌上。它们很安全。因此,在STL容器中的对象也很安全。我知道这个比喻听起来很老土,但是它很正确。 STL算法是标准算法,我们可以把它们应用在那些容器中的对象上。这些算法都有很著名的执行特性。它们可以给对象排序,删除它们,给它们记数,比较,找出特殊的对象,把它们合并到另一个容器中,以及执行其他有用的操作。 STL iterator就象是容器中指向对象的指针。STL的算法使用iterator在容器上进行操作。Iterator设置算法的边界 ,容器的长度,和其他一些事情。举个例子,有些iterator仅让算法读元素,有一些让算法写元素,有一些则两者都行。 Iterator也决定在容器中处理的方向。 你可以通过调用容器的成员函数begin()来得到一个指向一个容器起始位置的iterator。你可以调用一个容器的 end() 函数来得到过去的最后一个值(就是处理停在那的那个值)。 这就是STL所有的东西,容器、算法、和允许算法工作在容器中的元素上的iterator。 算法以合适、标准的方法操作对象,并可通过iterator得到容器精确的长度。一旦做了这些,它们就在也不会“跑出边界”。 还有一些其他的对这些核心组件类型有功能性增强的组件,例如函数对象。我们将会看到有关这些的例子,现在 ,我们先来看一看STL的list。 定义一个list我们可以象这样来定义一个STL的list: #include #include int main (void) list Milkshakes; return 0; 这就行了,你已经定义了一个list。简单吗?list Milkshakes这句是你声明了list模板类 的一个实例,然后就是实例化这个类的一个对象。但是我们别急着做这个。在这一步其实你只需要知道你定义了 一个字符串的list。你需要包含提供STL list类的头文件。我用gcc 2.7.2在我的Linux上编译这个测试程序,例如: g+ test1.cpp -o test1 注意iostream.h这个头文件已经被STL的头文件放弃了。这就是为什么这个例子中没有它的原因。 现在我们有了一个list,我们可以看实使用它来装东西了。我们将把一个字符串加到这个list里。有一个非常 重要的东西叫做list的值类型。值类型就是list中的对象的类型。在这个例子中,这个list的值类型就是字符串,string , 这是因为这个list用来放字符串。 使用list的成员函数push_back和push_front插入一个元素到list中#include #include int main (void) list Milkshakes; Milkshakes.push_back(Chocolate); Milkshakes.push_back(Strawberry); Milkshakes.push_front(Lime); Milkshakes.push_front(Vanilla); return 0;我们现在有个4个字符串在list中。list的成员函数push_back()把一个对象放到一个list的后面,而 push_front()把对象放到前面。我通常把一些错误信息push_back()到一个list中去,然后push_front()一个标题到list中, 这样它就会在这个错误消息以前打印它了。The list member function empty()list的成员函数empty() 知道一个list是否为空很重要。如果list为空,empty()这个成员函数返回真。 我通常会这样使用它。通篇程序我都用push_back()来把错误消息放到list中去。然后,通过调用empty() 我就可以说出这个程序是否报告了错误。如果我定义了一个list来放信息,一个放警告,一个放严重错误, 我就可以通过使用empty()轻易的说出到底有那种类型的错误发生了。 我可以整理这些list,然后在打印它们之前,用标题来整理它们,或者把它们排序成类。 这是我的意思: /*| Using a list to track and report program messages and status*/#include #include #include int main (void) #define OK 0 #define INFO 1 #define WARNING 2 int return_code; list InfoMessages; list WarningMessages; / during a program these messages are loaded at various points InfoMessages.push_back(Info: Program started); / do work. WarningMessages.push_back(Warning: No Customer records have been found); / do work. return_code = OK; if (!InfoMessages.empty() / there were info messages InfoMessages.push_front(Informational Messages:); / . print the info messages list, well see how later return_code = INFO; if (!WarningMessages.empty() / there were warning messages WarningMessages.push_front(Warning Messages:); / . print the warning messages list, well see how later return_code = WARNING; / If there were no messages say so. if (InfoMessages.empty() & WarningMessages.empty() cout There were no messages endl; return return_code;用for循环来处理list中的元素 我们想要遍历一个list,比如打印一个中的所有对象来看看list上不同操作的结果。要一个元素一个元素的遍历一个list, 我们可以这样做: /*| How to print the contents of a simple STL list. Whew!*/#include #include #include int main (void) list Milkshakes; list:iterator MilkshakeIterator; Milkshakes.push_back(Chocolate); Milkshakes.push_back(Strawberry); Milkshakes.push_front(Lime); Milkshakes.push_front(Vanilla); / print the milkshakes Milkshakes.push_front(The Milkshake Menu); Milkshakes.push_back(* Thats the end *); for (MilkshakeIterator=Milkshakes.begin(); MilkshakeIterator!=Milkshakes.end(); +MilkshakeIterator) / dereference the iterator to get the element cout *MilkshakeIterator endl; 这个程序定义了一个iterator,MilkshakeIterator。我们把它指向了这个list的第一个元素。 这可以调用Milkshakes.begin()来作到,它会返回一个指向list开头的iterator。然后我们把它和Milkshakes.end()的 返回值来做比较,当我们到了那儿的时候就停下来。 容器的end()函数会返回一个指向容器的最后一个位置的iterator。当我们到了那里,就停止操作。 我们不能不理容器的end()函数的返回值。我们仅知道它意味着已经处理到了这个容器的末尾,应该停止处理了。 所有的STL容器都要这样做。 在上面的例子中,每一次执行for循环,我们就重复引用iterator来得到我们打印的字符串。 在STL编程中,我们在每个算法中都使用一个或多个iterator。我们使用它们来存取容器中的对象。 要存取一个给定的对象,我们把一个iterator指向它,然后间接引用这个iterator。 这个list容器,就象你所想的,它不支持在iterator加一个数来指向隔一个的对象。 就是说,我们不能用Milkshakes.begin()+2来指向list中的第三个对象,因为STL的list是以双链的list来实现的, 它不支持随机存取。vector和deque(向量和双端队列)和一些其他的STL的容器可以支持随机存取。 上面的程序打印出了list中的内容。任何人读了它都能马上明白它是怎麽工作的。它使用标准的iterator和标准 的list容器。没有多少程序员依赖它里面装的东西, 仅仅是标准的C+。这是一个向前的重要步骤。这个例子使用STL使我们的软件更加标准。 用STL的通用算法for_each来处理list中的元素 使用STL list和 iterator,我们要初始化、比较和给iterator增量来遍历这个容器。STL通用的for_each 算法能够减轻我们的工作。 /*| How to print a simple STL list MkII*/#include #include #include #include PrintIt (string& StringToPrint) cout StringToPrint endl;int main (void) list FruitAndVegetables; FruitAndVegetables.push_back(carrot); FruitAndVegetables.push_back(pumpkin); FruitAndVegetables.push_back(potato); FruitAndVegetables.push_front(apple); FruitAndVegetables.push_front(pineapple); for_each (FruitAndVegetables.begin(), FruitAndVegetables.end(), PrintIt); 在这个程序中我们使用STL的通用算法for_each()来遍历一个iterator的范围,然后调用PrintIt()来处理每个对象。 我们不需要初始化、比较和给iterator增量。for_each()为我们漂亮的完成了这些工作。我们执行于对象上的 操作被很好的打包在这个函数以外了,我们不
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 河北省广宗县2025年上半年公开招聘村务工作者试题含答案分析
- 新型耐药基因发现-洞察及研究
- 澳门预测培训入门知识大全课件
- 铁路乘务员化妆课件
- 2025年工程地质期末考试题含答案
- 情景模拟培训优化-洞察及研究
- 2025年安徽省社区工作者招聘考试笔试试题(含答案)
- 铁塔寺消防安全知识培训课件
- 数据生命周身份管理-洞察及研究
- 知识产权贯标外审培训课件
- 迷彩九月+启航青春+课件-2025-2026学年高一上学期开学军训动员主题班会
- TCCEAS001-2022建设项目工程总承包计价规范
- 大学普通化学-课件文档
- 《植物生理学》课件第五章+同化物的运输
- 质量成长记-过程模式作业表
- 漆黑的魅影-精灵分布图鉴
- 小学语文分层作业设计
- 《只有一个地球》说课课件课件
- 200T钻具点压校直机技术方案
- 挡土墙计算书(共19页)
- 供配电技术实验指导书(09318)
评论
0/150
提交评论