当前位置:网站首页>虫子 STL string上
虫子 STL string上
2022-06-26 13:06:00 【华为云】
STL
什么是STL
STL(standard template libaray-标准模板库):==是C++标准库的重要组成部分==,不仅是一个可复用的组件库,而且==是一个包罗数据结构与算法的软件框架==
STL版本
原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本–所有STL实现版本的始祖
P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异
RW版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。
SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。==我们后面学习STL要阅读部分源代码,主要参考的就是这个版本。==
STL的六大组件
如何学习STL
简单总结一下:
==学习STL的三个境界:==
- 能用,
- 明理,
- 能扩展 。
==进公司前要把前两层修炼熟悉,第三层是在公司中修炼的==
STL的缺陷
- STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出
来已经相隔了13年,STL才进一步更新。- STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
- STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
- STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语
法本身导致的。
接下来我们要学的第一个容器就是string
为什么学习string类?
C语言中的字符串
C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问
标准库中的string类
string类(了解)
- 字符串是表示字符序列的类
- 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
- string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
- string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
- 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
==总结:==
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
- 不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include头文件以及using namespace std;
string类的常用接口说明(注意下面我只讲解最常用的接口)
1.string类对象的常见构造
(constructor)函数名称 功能说明 string() (重点) 构造空的string类对象,即空字符串 string(const char* s) (重点) 用C-string来构造string类对象 string(size_t n, char c) string类对象中包含n个字符c string(const string&s) (重点) 拷贝构造函数
==学STL,重点讲最常用30%左右的接口函数,其他很少用,如果有一天我们需要用,就去看文档==
int main(){ string s1; //无参构造 string s2("Hello c++"); //带参数构造 string s3 = "Hello c++";//编译器优化的直接构造 string s4(s2); //拷贝构造 string s5(s4, 2, string::npos); //部分构造 string s6("123456789", 5); //构造前n个字符 //这个作用就是假如以后要写网络的代码,截取前几个字符会用到 const char* url = "http://www.cplusplus.com/reference/string/string/string/"; string s7(url, 5); string s8(10, 'x'); //构造n个一样的字符 cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl; cout << s5 << endl; cout << s6 << endl; cout << s7 << endl; cout << s8 << endl; return 0;}
2.string类对象的容量操作
函数名称 功能说明 size(重点) 返回字符串有效字符长度 length 返回字符串有效字符长度 capacity 返回空间总大小 empty (重点) 检测字符串释放为空串,是返回true,否则返回false clear (重点) 清空有效字符 reserve (重点) 为字符串预留空间 resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充 ==实际上length在string中就是数组长度,和size一样,那为什么要两个一样的呢,是因为历史上string出来的要比stl早,string在官网文档也没有归类到容器里面(但他就是容器),而是放在了头文件里面,size是普法,length是只用与string的==
注意:
- size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
- clear()只是将string中有效字符清空,不改变底层空间大小。
- resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
- reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
==这里提一嘴 at 的作用和 [] 是一样的,可以认为是早期语法可能不太支持 [] 所以才有at这个接口代替,后面支持了,at就基本不用了,他们也不是完全一样,他们越界就不一样==
==reserve给足空间就可以防止多次增容,那么resize可以吗==
==我们也可以看看相同的代码在不同平台跑出来的结果==
int main(){ string s1 = "Hello world"; string s2 ="world"; //判断字符串是否为空 cout <<"s1.empty "<< s1.empty() << endl; cout << "s2.empty " << s2.empty() << endl; //大小 cout << "s1.size " << s1.size() << endl; cout << "s2.size " << s2.size() << endl; //容量 cout <<"s1.capacity "<< s1.capacity() << endl; cout <<"s2.capacity "<< s2.capacity() << endl << endl; //清掉所有的数据,就是size变成零,但是空间不释放 s1.clear(); cout << "s1.size " << s1.size() << endl; cout << "s1.capacity " << s1.capacity() << endl << endl; //在对象中插入n个字符,默认字符是‘\0’ //想要放其他字符就 s1.resize(15); string s3 = s2; s2.resize(1,'x'); s3.resize(16,'x'); cout <<"s2: "<< s2 << endl; cout <<"s3: "<< s3 << endl; cout << "s1.size " << s1.size() << endl; cout << "s2.size " << s2.size() << endl; cout << "s1.capacity " << s1.capacity() << endl; cout << "s2.capacity " << s2.capacity() << endl << endl; //请求一个容量的改变 s2.reserve(40); cout << "s2: " << s2 << endl; cout << "s2.size " << s2.size() << endl; cout << "s2.capacity " << s2.capacity() << endl << endl; string s4; ////直接给足空间防止多次增容 //s4.reserve(127); //看看resize可不可以防止多次增容 s4.resize(127); int old_capacity = s4.capacity(); for (char ch = 0; ch < 127; ch++) { s4 += ch; //查看增容情况 if (old_capacity != s4.capacity()) { cout << "增容:" << old_capacity <<"->"<< s4.capacity()<< endl; } old_capacity = s4.capacity(); } cout << s4 << endl << endl; return 0;}
3.string类对象的访问及遍历操作
函数名称 功能说明 operator[] (重点) 返回pos位置的字符,const string类对象调用 begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 rbegin + rend begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 范围for C++11支持更简洁的范围for的新遍历方式 ==迭代器==
==迭代器意义:像string,vector支持[]遍历,但是list,map等等容器不支持[],我们就要用迭代器遍历,所以迭代器是一种统一的使用方式==
int main(){ string s1 = "Hello c++"; //迭代器 string::iterator it = s1.begin();//begin是返回开始位置的迭代器 while (it != s1.end())//end是返回结束位置的迭代器 { static char tmp = 'a'; *it++ = tmp++; } it = s1.begin(); while (it != s1.end())//end是返回结束位置的迭代器 { cout << *it << " "; it++; } return 0;}
==反向迭代器==
int main(){ string s1 = "Hello c++"; //反向迭代器 string::reverse_iterator rit = s1.rbegin(); while (rit != s1.rend()) { cout << *rit << " "; rit++; } return 0;}
边栏推荐
- Beifu PLC based on NT_ Shutdown to realize automatic shutdown and restart of controller
- Some conclusions about Nan
- Beifu PLC realizes data power-off maintenance based on cx5130
- 三维向量的夹角
- Firewall introduction
- Network remote access using raspberry pie
- Stack, LIFO
- MySQL explanation (II)
- Custom encapsulation drop-down component
- 【系统分析师之路】第十五章 复盘数据库系统(数据库案例分析)
猜你喜欢
李航老师新作《机器学习方法》上市了!附购买链接
使用 Performance 看看浏览器在做什么
Cloudcompare - Poisson reconstruction
Beifu realizes the control of time slice size and quantity through CTU and ton
[how to connect the network] Chapter 2 (middle): sending a network packet
What is the use of index aliases in ES
Reprint - easy to use wechat applet UI component library
Mysql database explanation (III)
2021-10-18 character array
【MySQL从入门到精通】【高级篇】(二)MySQL目录结构与表在文件系统中的表示
随机推荐
MySQL数据库讲解(三)
Zero basics of C language lesson 8: Functions
H5视频自动播放和循环播放
Detailed introduction to shell script (4)
Es6: iterator
Echart stack histogram: add white spacing effect setting between color blocks
Global variable vs local variable
Connection migration for DataGrid configuration
ES6:Map
Stack, LIFO
基于PyTorch的生成对抗网络实战(7)——利用Pytorch搭建SGAN(Semi-Supervised GAN)生成手写数字并分类
Design of simple digital circuit traffic light
2021-10-18 character array
A primary multithreaded server model
A few lines of code can realize complex excel import and export. This tool class is really powerful!
Some conclusions about Nan
嵌入式virlog代码运行流程
Learn how to develop owl components by hand (7): practical use of owl projects
MySQL explanation (I)
Ring queue PHP