我们经常在应聘的网页上看到如下要求:“要求熟练掌握STL相关知识”。哦塞,这一下就吓倒一批人。没有接触过STL的朋友一定会觉得它很高深,结果本来可以试一下的工作机会就这样错过了。其实,STL不过是C++的一部分。这从STL的全称上就可以看出:STL 是Standard Template Library的缩写,中文名是标准模板库。哈哈,有什么了不起的?C++不就有很多库函数和资源?
知道这些,你就不用害怕它了吧?其实,要学习STL并非什么难事,它只不过就是这个世界上一些能人编写的算法精良、效率极高的一些代码的集合,它们和一般C++函数库的区别有两个:
1、STL是建立在模板概念上的代码,所以要求你必须对C++的模板概念有所了解;
2、STL拥有一套自己特有的数据存储模式,需要你慢慢熟悉。
本文旨在带领读者由一个最简单的代码例子做起,在这个简单例子中对STL培养起感情,慢慢走入STL的编程之旅。阅读本文的读者,需要了解C++的编程知识,最好对模板概念略知一二。
有些程序员会说:我干了这么多年编程了,一直也没使用过STL,也没影响我的工作。不错,没有STL是不会影响你的编程工作的。但STL是一些编程精英多年积累的精华代码,代码的可重用性特别强,而且具有很高的执行效率。你如果拥有了STL的使用技能,往往会使你的工作事半功倍。寥寥数行STL代码就可以替代一大堆你原来用传统C++代码写的程序。你看看,学习使用STL是不是很值得呢?
一个例子的引入:
有这样一个软件需求:
一个班级中有4个学生,现在需要按照学号排序,将4个学生的信息有序地存储在内存列表中,以便日后需要的时候调取。不过有一个特殊的情况:由于这些学生是刚刚考入学校的新生,他们是否来学校报到在录入的时候还不能肯定。因此,无论最终来多少学生报到,都要建立一个4元素的数组,然后一一输入他们的信息,代码如下:
typedef struct tag_Student
{
int nCode; // 学号
CString strName; // 姓名
}STUDENT;
STUDENT stu[4];
stu[0].strName = "张三";
stu[1].strName = "李四";
stu[2].strName = "王五";
stu[3].strName = "赵六";
stu[0].nCode = 1;
stu[1].nCode = 2;
stu[2].nCode = 3;
stu[3].nCode = 4;
这样就要为那些没有来报到的新生留下空位,如果他们最终根本就没有选择这个学校,学校就需要为他们永久地保留存储空间,造成存储空间的浪费。
那么有什么好办法呢?其实,如果你引入了STL的map就可以轻松地解决这个问题了。看下面的代码:
void FillMapList( map<int, tag_Student*> *pMap, int nIndex, tag_Student *pStu );
void main()
{
map<int, tag_Student*> mapName;
FillMapList( &mapName, 2, &stu[2] );
}
void FillMapList( map<int, tag_Student*> *pMap, int nIndex, tag_Student *pStu )
{
(*pMap)[nIndex] = pStu;
}
在main函数中,map<int, tag_Student*> mapName;的含义是:定义一个map模板的实例mapName,模板的第一个参数是模板的索引(index,也就是普通数组中的数组下标),用于索引数组中的元素;第二个参数tag_Student借用了上面代码定义的结构的指针。这样就定义了一个存储空间mapName,而此时mapName中尚未分配任何实际的内存空间。当你需要向mapName中存放数据的时候可以调用FillMapList函数。
对于FillMapList函数,第一个参数就是先前定义的mapName的指针;第二个参数是模板的索引;第三个参数是欲输入的数据。(*pMap)[nIndex] = pStu;的含义是:在pMap的第nIndex位置上保存输入的数据。
这样保存后的数据存储在pMap的逻辑位置上,也就是存放在2这个位置上,而0和1的位置并未分配存储空间,只有在需要的时候才会分配。这就是map存储结构巧妙的地方,它可以动态的分配空间,就相当于给你提供了一个链表结构,你可以随时在这个链表上添加节点,而这个链表还不用你维护。这样,既节省了空间,又使用了很少的代码,是不是很方便?