string类
头文件:#include
string类对象的常见构造
int main()
{
//string使用方法
string s1;
string s2("hello world");
string s3 = "hello world";//隐式类型转换
string s4(s3,6,3);
cout << s4 << endl;
string s5(s3, 6, 13);//超过范围,有多少取多少
cout << s4 << endl;
string s6(s3, 6);
cout << s6 << endl;
string s7("hello world", 5);
cout << s7 << endl;
string s8(10, '*');
cout << s8 << endl;
return 0;
}
运行结果:
string类对象的容量操作
代码如下:
int main()
{
string s1("hello world");
cout << s1.size() << endl;
cout << s1.length() << endl;
cout << s1.max_size() << endl;
cout << s1.capacity() << endl;
return 0;
}
运行结果:
string类对象的修改操作
代码如下:
int main()
{
string s1("hello");
s1.push_back(' ');//push_back:在字符串后尾插字符
s1.push_back('!');
cout << s1 << endl;
s1.append("world");//append:在字符串后追加一个字符串
cout << s1 << endl;
s1 += ' ';//operator+= : 在字符串后追加字符串str
s1 += '!';
s1 += "world";
cout << s1 << endl;
return 0;
}
运行结果:
string的结构
先看以下代码:
int main()
{
//观察扩容情况,1.5倍扩容,第一次扩容不同
string s;
cout << sizeof(s) << endl;
size_t sz = s.capacity();
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s.push_back('c');
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
return 0;
}
这段代码在vs下运行的结果:
vs下string的结构
string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字
符串的存储空间:
1.当字符串长度小于16时,使用内部固定的字符数组来存放
2.当字符串长度大于等于16时,从堆上开辟空间
这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内
部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量
最后:还有一个指针做一些其他事情。
故总共占16+4+4+4=28个字节。
这段代码在linux下运行的结果:
G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指
针将来指向一块堆空间,内部包含了如下字段:
1.空间总大小
2.字符串有效长度
3.引用计数
4.指向堆空间的指针,用来存储字符串。
string扩容
先看以下代码:
int main()
{
//扩容
string s1("hello world");
s1.reserve(100);
cout << s1.size() << endl;
cout << s1.capacity() << endl;
//扩容+初始化
string s2("hello world");
s2.resize(100,'x');
cout << s2.size() << endl;
cout << s2.capacity() << endl;
//比size小,删除数据,保留前五个
s2.resize(5);
cout << s2.size() << endl;
cout << s2.capacity() << endl;
return 0;
}
运行结果:
迭代器
begin/end
int main()
{
string s1("hello world");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
return 0;
}
运行结果