STL标准模板库理论基础
基本概念
STL的从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。
使用STL的好处
- STL是C++的一部分,因此不用额外安装什么,它被内建在你的编译器之内。
- STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但是这种分离确实使得STL变得非常通用。
例如,在STL的vector容器中,可以放入元素、基础数据类型变量、元素的地址;
STL的sort()函数可以用来操作vector,list等容器。 - 程序员可以不用思考STL具体的实现过程,只要能够熟练使用STL就OK了。这样他们就可以把精力放在程序开发的别的方面。
- STL具有高可重用性,高性能,高移植性,跨平台的优点。
高可重用性:STL中几乎所有的代码都采用了模板类和模版函数的方式实现,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。关于模板的知识,已经给大家介绍了。
高性能:如map可以高效地从十万条记录里面查找出指定的记录,因为map是采用红黑树的变体实现的。(红黑树是平横二叉树的一种)
高移植性:如在项目A上用STL编写的模块,可以直接移植到项目B上。
跨平台:如用windows的Visual Studio编写的代码可以在Mac OS的XCode上直接编译。 - 程序员可以不用思考STL具体的实现过程,只要能够熟练使用STL就OK了。这样他们就可以把精力放在程序开发的别的方面。
- 了解到STL的这些好处,我们知道STL无疑是最值得C++程序员骄傲的一部分。每一个C++程序员都应该好好学习STL。只有能够熟练使用STL的程序员,才是好的C++程序员。
总之:招聘工作中,经常遇到C++程序员对STL不是非常了解。大多是有一个大致的映像,而对于在什么情况下应该使用哪个容器和算法都感到比较茫然。STL是C++程序员的一项不可或缺的基本技能,掌握它对提升C++编程大有裨益。
容器
STL容器就是将运用最广泛的一些数据结构实现出来。
常用的数据结构不在乎,数组(array),链表(list),tree(树),栈(stack),队列(queue),集合(set),映射表(map),根据数据在容器中的排列特性,这些数据分为序列式容器和关联式容器两种。
容器的分类
- 序列式容器(Sequence containers)
每个元素都有固定位置--取决于插入时机和地点,和元素值无关。
vector、deque、list - 关联式容器(Associated containers)
元素位置取决于特定的排序准则,和插入顺序无关
set、multiset、map、multimap
迭代器
迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通 过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
迭代器部分主要由头文件<utility>,<iterator>和<memory>
组 成。
<utility>
是一个很小的头文件,它包括了贯穿使用在STL中的几个模板的声明,
<iterator>
中提供了迭代器 使用的许多方法,
而对于<memory>
的描述则十分的困难,它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生 的临时对象提供机制,<memory>
中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
算法
以有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms).
广义而言,我们所编写的每个程序都是一个算法,其中的每个函数也都是一个算法,毕竟它们都是用来解决或大或小的逻辑问题或数学问题。
STL收录的算法经过了数学上的效能分析与证明,是极具复用价值的,包括常用的排序,查找等等。
特定的算法往往搭配特定的数据结构,数据结构是问题的载体,算法与数据结构相辅相成。
算法分为:质变算法和非质变算法。
- 质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等
- 非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等
迭代器
迭代器(iterator)是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物。在<<Design Patterns>>
一书中提供了23中设计模式的完整描述,其中iterator模式定义如下:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。
迭代器的设计思维-STL的关键所在,STL的中心思想在于将数据容器(container)和算法(algorithms)分开,彼此独立设计,最后再一贴胶着剂将他们撮合在一起。从技术角度来看,容器和算法的泛型化并不困难,c++的class template和function template可分别达到目标,如果设计出两这个之间的良好的胶着剂,才是大难题。
C++标准库
C++强大的功能来源于其丰富的类库及库函数资源。C++标准库的内容总共在50个标准头文件中定义。在C++开发中,要尽可能地利用标准库完 成。这样做的直接好处包括:
(1)成本:已经作为标准提供,何苦再花费时间、人力重新开发呢;
(2)质量:标准库的都是经过严格测试的,正确性有保证;
(3)效率:关于人的效率已经体现在成本中了,关于代码的执行效率要相信实现标准库的大牛们的水平;
(4)良好的编程风格:采用行业中普遍的做法进行开发。
标准库中与语言支持功能相关的头文件
支持流输入/输出的头文件
与诊断功能相关的头文件
定义工具函数的头文件
支持字符串处理的头文件
定义容器类的模板的头文件
支持迭代器的头文件
有关算法的头文件
有关数值操作的头文件
有关本地化的头文件
案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
usingnamespace std;
//STL 中的容器 算法 迭代器
void test01(){
vector<int> v;//STL 中的标准容器之一 :动态数组
v.push_back(1);//vector 容器提供的插入数据的方法
v.push_back(5);
v.push_back(3);
v.push_back(7);
//迭代器
vector<int>::iterator pStart = v.begin();//vector 容器提供了 begin()方法 返回指向第一个元素的迭代器
vector<int>::iterator pEnd = v.end();//vector 容器提供了 end()方法 返回指向最后一个元素下一个位置的迭代器
//通过迭代器遍历
while(pStart != pEnd){
cout <<*pStart <<" ";
pStart++;
}
cout << endl;
//算法 count 算法 用于统计元素的个数
int n = count(pStart, pEnd,5);
cout <<"n:"<< n << endl;
}
//STL 容器不单单可以存储基础数据类型,也可以存储类对象
class Teacher
{
public:
Teacher(int age):age(age){};
~Teacher(){};
public:
int age;
};
void test02(){
vector<Teacher> v;//存储 Teacher 类型数据的容器
Teacher t1(10), t2(20), t3(30);
v.push_back(t1);
v.push_back(t2);
v.push_back(t3);
vector<Teacher>::iterator pStart = v.begin();
vector<Teacher>::iterator pEnd = v.end();
//通过迭代器遍历
while(pStart != pEnd){
cout << pStart->age <<" ";
pStart++;
}
cout << endl;
}
//存储 Teacher 类型指针
void test03(){
vector<Teacher*> v;//存储 Teacher 类型指针
Teacher* t1 =new Teacher(10);
Teacher* t2 =new Teacher(20);
Teacher* t3 =new Teacher(30);
v.push_back(t1);
v.push_back(t2);
v.push_back(t3);
//拿到容器迭代器
vector<Teacher*>::iterator pStart = v.begin();
vector<Teacher*>::iterator pEnd = v.end();
//通过迭代器遍历
while(pStart != pEnd){
cout <<(*pStart)->age <<" ";
pStart++;
}
cout << endl;
}
//容器嵌套容器 难点(不理解,可以跳过)
void test04(){
vector<vector<int>> v;//容器中存储容器
vector<int> v1, v2, v3;
v1.push_back(1);
v1.push_back(2);
v2.push_back(10);
v3.push_back(100);
v3.push_back(200);
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
//拿到容器迭代器
vector<vector<int>>::iterator pStart = v.begin();
vector<vector<int>>::iterator pEnd = v.end();
//通过迭代器遍历
while(pStart != pEnd){
vector<int> vTemp =*pStart;//获得迭代器当前指向的容器
vector<int>::iterator tmpStart = vTemp.begin();
vector<int>::iterator tmpEnd = vTemp.end();
for(; tmpStart != tmpEnd; tmpStart++){
cout <<*tmpStart <<" ";
}
cout << endl;
pStart++;
}
}
int main(){
//test01();
//test02();
//test03();
test04();
system("pause");
return EXIT_SUCCESS;
}
标签:容器,头文件,迭代,STL,标准,算法,vector,模板
From: https://blog.csdn.net/2401_83614570/article/details/140522262