string的模拟实现
- string的基本用法
- string的遍历(三种方式):
- 关于auto(自动推导):
- 范围for:
- 迭代器
- 普通迭代器(可读可改)
- const迭代器(可读不可改)
- string细小知识点
- string的常见接口
- 引用计数和写时拷贝(了解)
- 编码(了解)
string的基本用法
#include<iostream>
#include<string>//string要包含头文件`#include<string>
using namespace std;
int main()
{
string st1;//无参
string st2("1111");//带参
string st3(st2);//拷贝构造
cout << st1 << endl;
cout << st2 << endl;
cout << st3 << endl;
string st4(st2, 2);
cout << st4 << endl;
string st5("hello world", 3);
cout << st5 << endl;
string st6(10, 'x');
cout << st6 << endl;
string st7("hello world");
//opterator[],可以读和修改
st7[0] = 'x';
cout << st7 << endl;
}
运行结果:
string的遍历(三种方式):
//1.下标+[]
for (size_t i = 0; i < st7.size(); i++)
{
cout << st7[i];
}
cout << endl;
//2.迭代器(所有容器都可以用类似的方式)
string::iterator it = st7.begin();
while (it != st7.end())
{
cout << *it;
it++;
}
cout << endl;
//3.范围for(),自动赋值,自动迭代,自动判断结束
for (auto ch:st7)//auto代表自动推导类型
{
cout << ch<<" ";
}
cout << endl;
关于auto(自动推导):
主要用途:替换长类型,简化代码,但一定程度上牺牲了代码的可读性。
auto不能作为函数的参数,可以做返回值,但是建议谨慎使用。
// 不能做参数
void func2(auto a)
{}// 可以做返回值,但是建议谨慎使用
auto func3()
{
return 3;
}
auto不能直接用来声明数组。
// 编译报错:error C3318: “auto []”: 数组不能具有其中包含“auto”的元素类型
auto array[] = { 4, 5, 6 };
范围for:
适用于容器和数组的遍历。
int main()
{
int array[] = { 1, 2, 3, 4, 5 };
// C++98的遍历
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
{
array[i] *= 2;
}
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
{
cout << array[i] << endl;
}
// C++11的遍历
for (auto& e : array)
e *= 2;
for (auto e : array)
cout << e << " " << endl;
string str("hello world");
for (auto ch : str)
{
cout << ch << " ";
}
cout << endl;
return 0;
}
迭代器
普通迭代器(可读可改)
1.正向迭代器
string s1("hello world");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it;
it++;
}
cout << endl;
2.反向迭代器
string s1("hello world");
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
cout << *rit;
rit++;
}
cout << endl;
const迭代器(可读不可改)
1.const正向迭代器
const string s1("hello world");
string::reverse_iterator cit = s1.begin();
while (cit != s1.end())
{
cout << *cit;
cit++;
}
cout << endl;
2.const反向迭代器
const string s1("hello world");
string::const_reverse_iterator sit = s1.rbegin();
while (sit != s1.rend())
{
cout << *sit;
sit++;
}
cout << endl;
string细小知识点
开空间:reserve
string s1("hello world");
s1.reserve(100);//提前开好空间,避免扩容 reserve “保留”
求string的长度:size()(通用),length()(不具有通用性,C++向前兼容)
string s1("hello world");
cout << s1.size() << endl;
string的常见接口
void test()
{
string s("hello world");
s.push_back('x');//一次只能插入一个
s += 'g';
s += "hhh";//一般尾插用这个
//头插
s.insert(0, "nihao");
cout << s << endl;
}
void test2()
{
string s("hello world");
s.erase(1, 1);
//尾删
s.erase(s.size() - 1, 1);
cout << s << endl;
string s1("hello world");
//替换
s1.replace(5, 1,"%%");
cout << s1 << endl;
//替换所有的空格
string s3("hello world");
string tmp;
for (auto ch : s3)
{
if (ch == ' ')
{
tmp += "%d%d";
}
else
{
tmp += ch;
}
}
cout << tmp << endl;
void test3()
{
string s("test.cpp.zip");
size_t pos = s.find('.');
string s1 = s.substr(pos);
cout << s1 << endl;
size_t pos1 = s.rfind('.');
string s2 = s.substr(pos1);
cout << s2<< endl;
}
void test4()
{
string s("hello");
string s1 = s + "world";
cout <<s1<< endl;
getline(cin, str);//遇到换行才会停止
}
}
int main()
{
test();
return 0;
}
引用计数和写时拷贝(了解)
写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。
引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。
编码(了解)
编码:值和符号的映射关系
ASCII编码表本质是:英文符号和值的映射关系
统一编码:Unicode(万国码)
了解UTF-8,UTF-16,UTF-32;
GBK(国标):中国自己做了一套自己的编码;