王小明学STL
王小明最近又不安分了,自从学习了C++之后,开始目中无人,对学习其他语言的同学各种鄙视。
这次他又在向别人炫耀C++的指针是多么牛,不巧被大叔碰上了。
“你看指针多牛叉,连数组的括号都不用。”
“小明,过来,考考你。”大叔是他哪家子亲戚倒是不晓得。
“来,谁怕谁!”
“现在要你做一个可以存数据的东西,你实现一个?”
“这简单,数据就当是整型吧,我弄个数组就行了。”小明感觉这就是小菜一碟,三下五除二就写好了。
int array[5] = {0};
“看,怎样!够你存五个了,哈哈!”小明拍拍手想走人。
大叔却叫住了他,“存个1进去。”
“那还不简单。”
array[0] = 1;
“看来你还没忘了数组是从0开始的啊!存个2呢?”
array[1] = 2;
小明踌躇了一下,说,“再看这个。”
*(array+1) = 2;
“还用下标呢,你看。”小明得意极了,大叔则不慌不忙,“那再把3-5存进去。”
“这还不简单,看我的。”
int i; for (i=3; i<=5; i++) { *(array+i-1) = i; }
“这里用了循环,再用指针代替下标,不错吧!”到了这一步,周围的同学都看不过眼了,感觉大叔把小明都捧到天上去了。小明在一边得意,大叔却一点都不着急的样子。
“那你再把6放进去。”大叔慢慢地说。
array[5] = 6;
小明刚写下就后悔了,他发现一个致命的问题。很明显,刚开始申请的数组长度就只有5,现在要放进六个数据,明显不够用。周围的同学好像也发现了这个问题,在一边偷偷地笑,暗赞大叔的聪明。
突然,小明灵机一动,说,“我要把刚才申请的数组改一下。”
int array[10];
“这样就不会错了哈!”
“那我要存100个呢?”“那就开到100。”
“10000呢?”“那就开到10000。”
“那现在我只要用10个呢?”“很明显嘛,10000个够你用啦。”
“那不就浪费了吗?”
小明好像也觉得有点浪费,“那就重新给你开个10的行了吧!”但是小明也发现自己有点无理了,周围人也在笑自己。
等了好一会,才不好意思地说,“那你说怎么办?”
大叔看到他终于低下了头,“给你看个东西,这东西叫做容器。”
vector<int> array;
“啊,什么东西?”
“先看看怎么使用的。”
array.push_back(1); array.push_back(2); int i; for (i=3; i<=5; i++) { array.push_back(i); } for (i=6; i<=1000; i++) { array.push_back(i); }
“哇,怎么可以这样,它不用考虑数组的长度吗?”
“当然考虑,只是它隐藏了这些操作。你看看你说你会用指针,但是连基本的内存分配都不会用。”
int *array = new int[5]; delete[] array;
“你看看这样写,懂不?”
小明好像记起什么的样子,“new是用来分配内存的,这里就是申请了一个长度为5的数组,第二行是释放这个内存。其余操作都跟原来一样。”
“如果我觉得不够用,那我就把原来的释放掉,重新申请一个数组,同时将原来的数据复制过去就好了。vector的原理就是这个样子。”大叔有条不紊地解释着。
“哦,对,这样要多大的数组就有多大啦!”
“嗯,而vector的操作也和数组的一样,可以直接用下标去操作,当然这里面还包括了运算符的重载问题,这里就不讲了。”
“哦,那前面那个<int>是干嘛的,表示整型吗?”
“是表示整型,你也可以换成其他类型,比如double,char等。”
“操作都和原来一样吗?好牛啊!”
“不过,因为vector是别人写的东西,所以要用到的时候需要包含它的头文件。”
#include <vector> using namespace std;
“我平时都是这样写的。”
#include <iostream> using namespace std;
“看来我又多了个头文件可以写了,平时看别人包含那么多头文件,虽不觉,但明厉啊!”
大叔微笑着点点头。“vector是STL的一部分,十分方便。”
“这么说STL还有其他东西?肯定都很牛叉!”
“当然了!只要你好好学习,我可以慢慢教你。”
“你说说有什么先啦!”
“那我先考你,怎么从vector里去除一个数据。”
“这个……”小明摸摸头,“等我回去查了回来告诉你。”
话音刚落,王小明就飞也似地跑开了。