&1include&&vector&&2include&&iostream&&3&&4&using&namespace&&5&&6&void&showAddress(vector&int&&a)&{&7&&&&&int*&pb&=&&*a.begin();&&& //如果写成int* pb = a.begin();则编译器报错&8&&&&&int*&pe&=&&*a.end();&9&&&&&cout&&&&"a.size()&==&"&&&&a.size()&&&&'\n';10&&&&&cout&&&&pb&&&&"&-&&"&&&&pe&&&&'\n';11&}12&13&int&main(){14&&&&&vector&int&&a;15&//&&&&a.resize(a.max_size()/4,&0);&&&&//这行我们先不管,以后再玩16&&&&&cout&&&&"a.max_size()&==&"&&&a.max_size()&&&&'\n';17&&&&&showAddress(a);18&&&&&a.push_back(0);19&&&&&showAddress(a);20&&&&&a.push_back(0);21&&&&&showAddress(a);22&23&&&&&return&0;24&}25&
注意,第7和第8行,如果写成int* pb = a.begin();则编译器报错,原因是begin()返回的是一个迭代器,迭代器是容器的一个成员类型,无法被转换为int*,虽然迭代器和指针的作用一样,但是这么转不行。如果要取a中第一个元素的地址,得像上面代码第7行所写的那样,先取迭代器指向的值,再取其地址。运行结果:
a.max_size()&==&&&&&&& //这个是a能容纳的最多的元素个数,看着玩a.size()&==&00&-&&0a.size()&==&10x8aa6018&-&&0x8aa601ca.size()&==&20x8aa6008&-&&0x8aa6010
可以看到,刚开始a的大小是0。begin()和end()返回的是空迭代器,地址空,所以指针为0。然后我们在第18行代码用push_back()插入一个元素,a的大小变成1,此时begin()和end()返回的是指向头和尾两个元素的迭代器,可以看到,a的大小为1,但是有两个元素,从0x8aa6018&-&&0x8aa601c正好差4,一个int。然后第20行代码再插一个元素,a的大小变成2,地址差8,两个int。有趣的部分来了,如果用front()和back()来取第一和最后一个元素的值,然后再窥探其地址,结果会一样么?修改代码如下,和上一个代码唯一不一样的是第7和第8行:
&1include&&vector&&2include&&iostream&&3&&4&using&namespace&&5&&6&void&showAddress(vector&int&&a)&{&7&&&&&int*&pb&=&&a.front();&8&&&&&int*&pe&=&&a.back();&9&&&&&cout&&&&"a.size()&==&"&&&&a.size()&&&&'\n';10&&&&&cout&&&&pb&&&&"&-&&"&&&&pe&&&&'\n';11&}12&13&int&main(){14&&&&&vector&int&&a;15&//&&&&a.resize(a.max_size()/4,&0);&&&&//这行我们先不管,以后再玩16 //&&&&cout&&&&"a.max_size()&==&"&&&a.max_size()&&&&'\n';17&&&&&showAddress(a);18&&&&&a.push_back(0);19&&&&&showAddress(a);20&&&&&a.push_back(0);21&&&&&showAddress(a);22&23&&&&&return&0;24&}25&
运行结果如下:
a.size()&==&00&-&&0xfffffffca.size()&==&10x9fd7018&-&&0x9fd7018a.size()&==&20x9fd7008&-&&0x9fd700c
一开始a的大小是0,所以取front()得到的是null。有趣的在下面,back()取出来的值的地址是0xfffffffc,而且无论程序运行多少次都不会变,说明不是随机地址,并且0xfffffffc加4就是0x,加1个int就回到了0。接下来的表现也不同,当a的大小为1时,front()和back()取出的是同一个元素,当然啦,第一个和最后一个元素一样。当a的大小为2时,两个地址差4,即1个int的大小,不是差2个。结论:begin()和end()给出的是指向第1个和第1+size个元素的迭代器(即最后一个元素之后的一个元素的迭代器)。front()和end()给出的是第1和第size个元素的值。提问,是不是这么说来end()所指向的值永远都是'\0'?为了验证,给出以下代码:
&1include&&vector&&2include&&iostream&&3&&4&using&namespace&&5&&6&void&showEnd(vector&int&&a)&{&7&&&&&cout&&&&"*a.end()&==&"&&&&*a.end()&&&&'\n';&8&}&9&10&int&main()&{11&&&&&vector&int&&a;12&&&&&showEnd(a);13&&&&&a.push_back(7);14&&&&&showEnd(a);15&&&&&a.push_back(7);16&&&&&showEnd(a);17&18&&&&&return&0;19&}20&
编译通过,运行结果:Erreur&de&segmentation这是法语(ubuntu-10.10法语的locale),英语的意思是Segmentation fault,我无法理解这个运行时错误。WinXP下也是编译通过,运行结果:弹出对话框“testvector.exe 遇到问题需要关闭。我们对此引起的不便表示抱歉。”点击“不发送”,在命令行中有如下结果:“Process returned - (0xC0000005)&& execution time : 12.891 sPress any key to continue.”目前不能理解,望高手解答。小弟不胜感激。然后我们把第12行的showEnd注释掉,编译,通过,运行结果:
*a.end()&==&0*a.end()&==&0
这个结果是分别在a中添加两个int元素之后取end()指向的值,可以得到的结论,即size为1和2,非0时,取end()所指的元素得到的结果是0。当size为0时,取end()所指元素得到的结果是运行时错误“Segmentation fault”。所以要当心size为0,对end()的使用。接下来我们来玩第一个源代码中的第15行,a.resize(a.max_size()/4, 0);a的尺寸会变得很大,并且3次showAddress都会操作这个庞然大物,观测内存,在虚拟机ubuntu下内存在10秒内轻松突破1G多。。。只感觉virtualbox突然一卡,硬盘狂闪,因为虚拟机中ubuntu的swap实际上就是读写硬盘。。。直到耗尽swap内存,然后throw出如下:
a.max_size()&==&terminate&called&after&throwing&an&instance&of&'std::bad_alloc'&&what():&&std::bad_allocAbandon
显然是没有再多内存可分配了。查看如下两篇blog,稍微了解到,编写STL需要注意程序效率问题,否则STL也不是万能的。。。/janvyking999/blog/item/2b3dbd547f50dbcdb745ae05.html/hins_pan/blog/item/515bd2a3cc2b8a.html都是介绍Effective STL这本书的。有关如何取迭代器所指向的值的地址,查看了如下帖子:如何将 迭代器的指针转换成 DWORD/showpost.asp?id=17059最后总结:begin()和end()返回的是迭代器,指向第1和第1+size个元素。front()和back()返回的是元素的值,指向第1和第size个元素。注意在size为0和1时两种方法的区别。所遗留的问题,目前还不知道对于一个容器的名字,编译器会返回什么。(比如数组的名字返回的是第一个元素的地址)此问题所引申的问题就是容器如果作为其他函数的参数时,传地址和传值的区别。本文测试环境默认为ubuntu-10.10搭配g++ 4.4.5,各别指明处为winxp sp3搭配g++ 4.5.0。真正要搞STL还得啃标准库源码。
&re: STL学习笔记[未登录]&&&&
@jmchxy多谢大哥,突然明白开闭区间的作用了。ok,修改原文:接下来有趣了!一开始a的大小是0,所以取front()得到的是null。不过“size为0时back()所得元素的地址为0xfffffffc”这一点,还不理解,因为这个现象表示,back()得到的地址比front()得到的地址小4,即1个int。back()跑到front()前面去了。
&re: STL学习笔记&&&&
@jmchxy我修改了第三段源码,把第12行注释掉了,即size为0时,不取end(),在size为1和2,非0时再取end(),结果*a.end()都是0。就是说当且仅当size为0时取end()才会有Segmentation fault错误。
&re: STL学习笔记&&&&
没必要看源代码,手册已经很清楚咧。。。
&re: STL学习笔记&&&&
@空明流转多谢大侠踩过,偶前面去大侠主页看过了,很有意思的成长经历。
&re: STL学习笔记&&&&
厚街翻译的一本stl手册??挺好的,中文版手册
&re: STL学习笔记&&&&
@zjhNicolai M. Josuttis 写的 The C++ Standard Library
阅读排行榜
评论排行榜举报该问题:
含有法律法规禁止的内容
含有违反《玩家守则》的内容
含有违反《推广员守则》的内容
含有无意义的内容
含有广告相关的内容
含有抄袭或***行为的内容
含有不文明言论的内容
含有信息安全问题的内容
含有游戏意见或建议反馈的内容
含有与“知道”定位不符的内容
楼主指定最佳***
两个门派各有利弊,不能简单地说那个好或者不好
DT早期能看出优势,即使没有攻修也能有很高的伤害输出,技能决定了他的地位,大堂毕竟是新人(新手)首推的门派,入手不会太难,而且容易造就高手
STL原先并不是很出名,一直被大堂压制,一提起物理攻击门派就是大堂,改变STL地位的是套装系统变身套装的出现影响了很多的战术,变相的相当于一个多秒的龙宫,而且强大的物理伤害输出让所有人再次重视起STL,所以要想玩高级别的STL必备一幅变身套装。
你的情况不是大堂和STL的选择,而是你更喜欢那个门派,两个门派都很适合周末的活动,也很受用欢迎,也都容易成为高手至于投入,后期投入都很大!都需要三修,都需要买男号装备所以都不便宜,所以别想省钱了
个人喜欢STL,因为大堂总想在鬼门关门口转悠,用血来换取伤害!而STL要好一些!
擅长:任务玩法
官阶:郡王
其它高悬赏问题
网易通行证您的举报已经提交成功,我们将尽快处理,谢谢!
地府是一个很悬乎的门派,加点方式不同可以自成1家。魔族力量的高成长和技能的高提成,使得力地府横空出世。但是不管是力地府(3力2血)还是纯血及血防(2血3防或3血...
1.象形后可以招BB
2.鹰击后可以招宝宝,也可保护对友,但不能吃药。
3.连击后不能招宝宝
4.鹰最多6次,90级4次,120级5次,150级6次
0。5耐定下,0。5体定下,3。5力定下。既然你准备4力,那么我的建议是。4力半耐半体。装备衣服优先月亮。帽子前几级月亮后面太阳。
我也来说一下,4。5力半敏...
直线5血 5血你都不用人民币!因为你不用点法功(点这个修炼也是白点!)物理攻击随你便了!说白了 你可以比别人少点1个修炼 你认为省钱吗?
什么++力量 害你呢...
鼠标右键使用,如果你做过10级的高大?b任务就不会问了。。。
大家还关注