目录
- 传统艺能????
- 嘛是STL????
- 内容????
- 重要性????
- string 类????
- 对象的常见构造????
- string 的遍历????
- append????
传统艺能????
嘛是STL????
STL是Standard Template Library的简称,标准模板库,它不仅是可复用的组件库,也是一个包罗数据结构与算法的软件框架。它是惠普实验室(HP)开发的一系列软件的统称,这可能是一个历史上最令人兴奋的工具的最无聊的术语。但是人家本这伟大的开源精神,声明允许任何人修改,拷贝,传播甚至商用但是唯一的条款就是使用者也需要开源。
STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件,STL现在是C++的一部分,因此不用额外安装什么。
惠普作为原始版本,后续悠悠大佬来进行把玩走出了三个版本:
1. P.J 版本
P.J.Plauger 开发,继承HP版本,被 windows visual C+采用,不被公开和修改,可读性差,符号命名怪异,所以 windows 一直以来闭源这也是看的出来的。
2. RW 版本:
由同名公司开发,继承HP版本,被 C++ builder 采用,不被公开和修改,可读性稍稍好一点,但是 builder 是 20 年前的编译器,当时这还是个C++嘎嘎牛的编译器,只是后面被 vs 这名猛将扳倒了,中道崩殂也是实在可惜。
3. SGI 版本:
这是作为STL学习参考的主要版本,继承HP版本,被 g++(Linux) 采用,移植性好并且做了开源,阅读性也是非常的高。后面推荐去阅读侯捷老师的《STL源码剖析》,恕我直言不知道侯捷老师,你要说你是学习C++的,那必定是有水分的。
有人说:为何某些公司不允许使用 C++ STL?
现在 Powerpoint 早已解禁 STL,源码里面漫山遍野的模板,然而 Word 没有,代码仍然一股汇编味,一个函数调用 20 个参数五个 out…大家自己去细品
内容????
STL包含六大组件:
所谓的算法和容器就是对应我们常说的算法和数据结构,容器就是数据结构。
重要性????
C++是一门很棒的语言,唯一的缺陷就是相关的库太少,不是因为大家不想为它写库,而是它的库很难写。而STL是C++v的标准模板库,里面封装了很多经典的算法,再加上是基于模板的,适用于多种数据类型,某种程度上说是通用算法,所以它在C++中的地位很高。就拿咱题目说,一个能用 C++ 解决的题,有些也支持C语言实现,但是一句 STL 能搞定上的在C里面可能会需要搞出二级指针这种属实恶心人的东西。
学 C++ 不学STL(现在叫标准程序库或许好点,后者对STL有所改进,应该算是STL的超集),一定是你人生一大遗憾,可惜现在很多学校教 C++ 的时候,根本没有提到过STL。
所以论STL重要性,这个问题本身就是个问题,不清楚 STL 地位的 C++ 学习者什么成分咱就不说了。
string 类????
我为什么想第一个针对学习 string 类?原因很简单,早在C语言阶段就学习了字符串,为了操作方便,C语言标准库提供了一堆有关字符串操作的函数——str 系列函数,但这些函数是和字符串分开的,不太适合OOP的思想,而且底层空间需要用户自己管理,稍不留神就会越界访问。
从定义来看,string 类是一个 typedef 的模板,而其实库里面并不仅仅只有一种 string,还有下面这些个玩意儿:
为什么会有这么多派生?其实这就要牵扯到编码问题。我们知道从最早的 ASCII 码到后来的 unicode(统一码也叫万国码,世界语言的映射表),unicode 又包含了 utf-8,utf-16,utf-32,再到后来的 gbk(国标扩展,针对汉字的映射表),其实网络上的敏感词屏蔽机制就是利用了编码。
为什么 string 会设计成模板就是因为原本的 string 管理对象是 char 类型,能够很好的去兼容英文,但是像 gbk 编码的汉字就需要两个字符表示,这时就需要一个新的类来支持汉字,所以我们把 string 搞成模板就是为了适应不同的编码。
他虽然是模板,但是使用时不需要 .h 头文件,直接
#include
即可使用。他之所以不加 .h 就是因为C语言已经有一个 string.h 了,这里会产生冲突发生链接错误。当然直接使用 string 类型比如: string a 这种定义方式是错误的,因为C++标准库的东西都是放在 std 标准命名空间的。
对象的常见构造????
string 类对象的构造方法有上百种,我们不可能全部记住,重点记住几个重要常见的就行了
注意无参构造 s1 里面并不是什么都没有,从底层来讲 s1 底限也会有一个 ‘\0’ 在里面。
在 s7 这种构造里面,构造表达式为
string(const string& str,size_t pos,size_t len = npos);
这里的这个 npos 又是个啥?他是个半缺省的声明,这个 npos 其实是一个成员变量
这里的 static const size_t npos = -1,-1 的补码是全1,给到无符号数身上就是最大值,npos 内涵就是无符号数的上限范围 4294967295,你有多少就能给你取多少。
但是总的来说并不是内容越多越好,string 类的 106 种成员接口很多都让他在C++中显得非常冗余,陈皓老师的《STL的 string 类怎么啦》一文中就对他提出了批评。
string 的遍历????
其实上面对 string 的拷贝啥的都不是问题,真正的问题在于怎么去遍历 string 的每一个字符,比如我们需要做翻转 string 的操作。
遍历 string 有三种方式:
- 下标+[] 访问
和数组有异曲同工之妙,我们依然可以用循环的方式遍历他
- 迭代器
这里迭代器只做演示,后面我想专题讲解迭代器。现阶段可以认为它是个像指针或者就是指针的东西,s1 里面有一段空间,begin 返回里面内容的开头位置,而 end 不是最后一个数据而是最后一个数据的下一个位置,所以他是一个开区间,这里 while 为什么使用 != 而不用 < 呢, != 在这里是一种相对标准的语法,后面的链表或者 map,他们的迭代器并不是原生的而是封装的,用 < 就达不到目的了。
- 之前讲过的范围 for
范围 for 对于遍历确实方便,毕竟 auto 关键字可以自动识别类型,但是如果有需要进行走动(比如双指针靠拢的遍历)的场景就没什么大用了。
append????
我们在 string 里面插入单个字符或者批量初始化为同一个字符是可以的,那可不可以插入字符串呢?答案一定是可以的,我们引入了 append 接口。
append 也和 string 一样接口一大堆,所以我们依然取其精华去其糟粕
string& append (const string& str);
string& append (const char* s);
但是我想告诉你,append 并不是最佳人选,真正的利器是 operator+= ,可以直接进行各种操作,又好读又好写何乐不为。
今天先到这里吧,润了家人们。