目录
1、STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
1、STL版本
1、原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP版本--所有STL实现版本的始祖。
2、P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低, 符号命名比较怪异。
3、RW版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder采用,不能公开或修改,可读性一般。
4、SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码, 主要参考的就是这个版本。
2、STL的六大组件
2、string类
string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类。
为什么会出现basic_string模板类?
计算机起源于美国,表示英语仅需要表示26个英文字母及相关的符号,计算机中存的是01序列,用8个比特位即1byte就可以表示完成,但随着计算机的普及,其他语言用1byte不一定能表示完,例如:中文就1万多汉字,1byte即256种显然不能表示完成。所以出现了char、wchar等类型,string采用的就是char类型的。
编码:将值和符号建立映射关系。形成编码表。
ASCII编码表——表示英文
Unicode——表示全世界文字编码表。包含utf—8、utf1—6、utf—32
gbk——中文自己量身定做的编码表
1、string类的常用接口说明
头文件包含#include<string>
1、string类对象的常见构造
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1; //构造空的string类对象
string s2("hello world");//使用字符串构造string类对象
string s3(s2); //使用s2拷贝构造s3
return 0;
}
2、string类对象的容量操作
void test2()
{
string s1("hello");
cout<<s1.size()<<endl;//返回字符串的有效长度,不包含最后作为结尾标识符的'\0'
cout << s1.length() << endl;
cout << s1.capacity() << endl;
cout << s1.empty() << endl;
s1.clear();// 将s1中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
cout << s1.size() << endl;
cout << s1.capacity() << endl;
}
1、reserve——只开空间,影响容量
void test3()
{
string s1("hello");
cout<<s1.size()<<endl;
cout << s1.capacity() << endl;
s1.reserve(100);//申请至少能存储100个字符的空间
cout << s1.size() << endl;
cout << s1.capacity() << endl;
}
2、resize——开空间,对这些空间给一个初始值进行初始化
void test4()
{
string s1("hello");
string s2(s1);
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.resize(10);//不给,默认用'\0'
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s2.resize(10, '*');
cout << s2 << endl;//string类对象支持直接用cin和cout进行输入和输出
}
注意:
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。
3、string类对象的访问及遍历操作
注意:这里是引用返回,也就是说可以修改返回对象
4、string类对象的修改操作
void test9()
{
string s1("hello");
s1 += "***";//追加字符串
cout << s1 << endl;
cout << s1.c_str() << endl;//返回C格式的字符串
}
5、string类非成员函数
2、string类的3种遍历方式
1、下标+[ ]
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello world");
//下标+[]遍历
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << " ";
}
cout << endl;
//下标+[]遍历、修改
for (size_t i = 0; i < s1.size(); ++i)
{
s1[i] += 1;
cout << s1[i]<<" ";
}
cout << endl;
return 0;
}
2、迭代器
将迭代器想象成像指针一样的类型
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello world");
//使用迭代器遍历
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//使用迭代器遍历+修改
string::iterator it2 = s1.begin();
while(it2 != s1.end())
{
*it2 += 1;
cout << *it2 << " ";
++it2;
}
cout << endl;
return 0;
}
3、范围for
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello world");
//范围for遍历
for (auto e : s1)//依次取s1中的值赋值给e
{
cout << e << " ";
}
cout << endl;
//范围for遍历+修改
for (auto& e : s1)
{
e += 1;
cout << e << " ";
}
cout << endl;
return 0;
}
4、反向迭代器
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1("hello world");
string::reverse_iterator it = s1.rbegin();
while (it != s1.rend())
{
cout << *it << " ";
++it;
}
cout << endl;
return 0;
}
注意:所有容器都可以使用迭代器这种方式去访问修改,属于通用遍历方式。