【C++进阶一】STL和string
【C++进阶一】STL和string
- 1.STL库的版本以及缺陷
- 2.STL库六大组件
- 3.string
- 4.string类对象的常见构造
- 5.string类对象的容量操作
- 5.1size和capacity接口函数
- 5.2empty和clear函数
- 5.3resize和reserve函数
- 6.迭代器以及string的访问和遍历
- 6.1反向迭代器
- 7.运算符重载[ ]
- 8.string类对象的修改操作
- 8.1push_back
- 8.2append
- 8.3operator+=
- 8.4c_str和find函数
- 9.insert和erase函数
- 9.1insert插入
- 9.2erase删除
1.STL库的版本以及缺陷
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要阅读部分源代码主要参考的就是这个版本
P.J版被Windows系统采用
SGI版被Linux系统采用
STL库的缺陷:
- STL库的更新太慢了,上一版靠谱是C++98,中间的C++03只有一些修订,到C++11出来已经相隔了13年,STL才有进一步更新
- STL现在都没有支持线程安全,并发环境下需要我们自己加锁,且锁的粒度是比较大的
- STL极度的追求效率,导致内部比较复杂,比如:类型萃取,迭代器萃取
2.STL库六大组件
进阶:各种算法、string vector、list stack、queue deque、priority_queue、仿函数
高阶:map和set、AVL数和红黑树、哈希
3.string
STL库函数的使用都要查看C++字典来学习接口函数并且模拟实现
string是表示字符串的字符串类,该类的接口与常规容器的接口基本相同,在此之上添加了一些专门用来操作string的常规操作
必须包含头文件< string >
4.string类对象的常见构造
- 用一个字符串构造
string str("pacify");
- 用一个字符构造
string str('Z');
- 用n个字符c构造
string str(10,'B');
- 用一段迭代器区间构造
string tmp("pacify");
string str(tmp.begin(),tmp.end());
在string和vector中,迭代器就是普通指针
- 拷贝构造
string temp("pacify");
string str(temp);
5.string类对象的容量操作
5.1size和capacity接口函数
size和capacity是成员函数,用
.
或者->
访问
int main()
{string str("pacify");int size = str.size();int capacity = str.capacity();//空间大小return 0;
}
5.2empty和clear函数
empty函数:若类对象是空串,就返回true;若不是空串就返回false
clear函数:
- clear后,使用empty会返回true
- clear函数只将size清零
- clear函数不会改变capacity
5.3resize和reserve函数
resize函数:
- 此函数既能改变size也能改变capacity
- 可以在不初始化的情况下直接将size扩为n
- 将size扩为n并且用n个字符c初始化
reserve函数:
- 此函数只改变capacity不改变size
不用reserve,每次扩容1.5倍
使用reserve,提前开辟空间,减少扩容,提高效率
6.迭代器以及string的访问和遍历
迭代器:iterator
(像指针一样的类型,用法和指针相似)
函数名.begin()
返回第一个位置的迭代器
函数名.end()
返回size位置的迭代器
string str("pacify");
string::iterator it = str.begin();
while(it != str.end())
{cout<< *it <<endl;//迭代器可以像指针一样++和--,也可以解引用拿到指向的内容it++;
}
6.1反向迭代器
反向迭代器: reverse_iterator
顾名思义是倒着走的迭代器,和反向迭代器相对应的是rbegin和rend函数
string s("pacify");
string::reverse_iterator rit = s.rbegin();
while(rit != s.rend())
{cout << *rit;rit++;
}
rit++是往前走,打印yficap
7.运算符重载[ ]
它可以让我们像使用数组一样随机访问string类对象中的字符
string str ("pacify");
for (int i = 0; i < str.size(); ++i)
{cout << str[i];
}
并且string类会检查[]是否越界
8.string类对象的修改操作
8.1push_back
在字符串后插入字符
string str("paci");
str.push_back('f');
str.push_back('y');
//str现在是:pacify
8.2append
在字符串后插入字符串(append不常用,+=常用)
8.3operator+=
字符串后插入字符/字符串/对象
string tmp("WORLD");
string str("wo");
str += 'r';
str += "ld";
str += tmp;
//str现在为worldWORLD
8.4c_str和find函数
c_str:const char*类型的指针
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("hello world");cout << s << endl;//自定义类型 运算符重载<<cout << s.c_str() << endl;//返回一个const char*指针,按照字符串打印,遇见'\0'结束return 0;
}
find函数:
查找字符,找到了返回当前pos位置的下标,没有找到就返回npos(整形最大值)
size_t find (char c, size_t pos = 0) const;
9.insert和erase函数
9.1insert插入
- 在pos位置前插入一个字符串
string& insert (size_t pos, const string& str);
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("world");s.insert(0, "hello");//0位置前插入字符串cout << s << endl;//helloworldreturn 0;
}
- 在pos位置前插入n个字符
string& insert (size_t pos, size_t n, char c);
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("world");s.insert(0,1,'!');//pos位置插入1个字符!cout << s << endl;//!worldreturn 0;
}
- 在迭代器前插入一个字符
iterator insert (iterator p, char c);
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("helloworld");s.insert(s.begin()+5, '!');cout << s << endl;//hello!worldreturn 0;
}
s.begin()代表开头的位置,s.begin()+5代表w的位置,在w之前插入字符!
9.2erase删除
- 从pos位置开始删除len个字符
string& erase (size_t pos = 0, size_t len = npos);
npos代表缺省值,即整数最大值
若len长度大于字符pos位置后的长度或者不给len值自动使用了npos, 则pos位置开始全的部删除
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("hello world");s.erase(0, 5);cout << s << endl;// worlds.erase(2);//2位置开始全部删除cout << s << endl;// w
}
- 从迭代器位置开始删除
iterator erase (iterator p);
#include<iostream>
#include<string>
using namespace std;
int main()
{string s("hello world");s.erase(s.begin()+1);cout << s << endl;//hllo world
}