在标准库中提供了顺序容器,今天稍总结下~
我们常见的顺序容器有:vector、deque、list、forward_list、array、string;
这篇文章,主要是大致了解下这几种容器
首先,我们先来看看vector 和string;
为什么把它们两放一起呢?
因为它们两很像。vector为向量,也就是可变大小的数组;string即表示字符串,每个单元存储的元素自然就是char了。
二者存储方式很像,它们都将元素保存在连续的空间里,好比是一栋楼,大家都按照顺序入住。这种存储方式就有以下几种特点:
1.既然大家的存储的地址是连续的,那我就可以按照元素下标直接计算出地址,然后实现对该元素的访问(好比我知道你是第四个入住的,那么我知道第一个的地址后,顺后第4间房就能直接找到你啦)。也就是能支持快速随机访问。
2.地址是连续的也有不好的一点,就是在非尾部添加或者删除元素的时候不得不把该位置以后的所有元素拷贝到另一个空间,然后把这个元素处理完之后,再把安置在别处的元素接上去。(还是那入住来做比喻,既然大家是按照顺序住的,那么假如有一天,有一个祖宗想加入这个队伍中,想住4号房,那怎么办?只能把原4号及之后的这些小罗罗先腾出来,然后安置好这祖宗之后,其他人再按照原来的先后顺序依次入住)所以,对它们两在尾部之外的位置插入或者删除元素就可能很慢了。
好~现在我们来侃侃这两货的成员函数,网上很多这里就不再赘述,详见
http://blog.csdn.net/phoebin/article/details/3864590
这里重点提几个
c.erase(pos);该函数目的是删除pos位置下的元素,也就是pos实际上是指向该元素的地址。使用该函数的时候就要注意避免产生指针越界溢出。函数返回擦除元素的下一个元素的位置。
例:
//用下例删除某元素不会出现越界
vector<student>::iterator iter;
for (iter = S.begin(); iter !=S.end();)
{
if ((*iter).get_name() == c || (*iter).get_stunumber() == c)
iter = S.erase(iter);//此时iter已经加一了
else
iter++;
}
//有兴趣的读者可以尝试下下面这个
vector<student>::iterator iter;
for (iter = S.begin(); iter !=S.end();iter++;)
{
if ((*iter).get_name() == c || (*iter).get_stunumber() == c)
iter = S.erase(iter);//此时iter已经加一了
}
//上面这个程序乍一看貌似也能完成功能,但是如果删除该序列的最后一个元素时就会发现程序会抛出异常,就是指针越界了!为什么会这样呢?原因在于当擦除最后一个元素的之后返回了S.end()了,而紧接着你又要进行iter++操作,这个时候指针就不知道指向谁了,也就是产生了一个野指针。自然会报错了。
成员函数还有一些注意细节见下一篇