1.string类对象的容量操作
函数名称 | 功能说明 |
size | 返回字符串有效长度 |
length | 返回字符串有效长度 |
capacity | 返回总空间大小 |
empty | 检测字符串是否为空,为空返回true,否则false |
clear | 清空有效字符 |
reserve | 为字符预留空间number大小空间 |
resize | 将有效字符改为n个,多出的字符用字符c填充(c为自己设置的字符) |
注意:1.size()与length()方法底层实现原理完全相等,引入size()的原因是为了与其它容器接口保持一致,一般情况都用size(),如果对象是字符串类的则length可以,其它的用可能会出现错误
2.clear()只是将string中有效字符清空,不改变底层空间的大小
3.resize(size_t)与resize(size_t,char c)都是将字符串中有效字符个数改变到n个,不同的是但字符个数增多时:resize(n)是用0来填充多出的元素空间,resize(size_t n,char c)用字符c来填充多出的元素空间。resize在改变元素个数时,如果是将元素增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间最大小不变。
4.reserve(size_t res=0):为string预留空间,不改变有效元素个数,但serve的参数小于string的底层空间总大小时,reserve不会改变容量大小。
2.string类对象的访问及遍历操作
函数名称 | 功能说明 |
operator[] | 返回pos位置字符,const string类对象调用 |
begin+end | begin获取第一个字符的迭代器+end获取最后一个字符下一个位置的迭代器(左闭右开) |
rbegin+rend | rbegin获取容器最后一个元素的逆向迭代器+rend获取容器第一个元素之前的逆向迭代器 |
范围for | C++11支持更新简洁的范围for遍历方式 |
3.代码演示
1.
string s1;
string s2("hello world");
cout << s1 << s2 << endl;
s2[0] = 'x';
cout << s1 << s2 << endl;
先构建俩个string类型的对象,s1没有初始化所有打印出来是空的,s2还进行了operator[],对索引0的地方进行重新赋值,所以h变为了x
2.
for (size_t i = 0; i < s2.size(); i++)
{
cout << s2[i] << " ";
}
cout << endl;
size()可以获取s2字符串总长度,然后[]可以获取对于索引的元素
3.
// 2、迭代器
//string::iterator it = s2.begin();
auto it = s2.begin();
while (it != s2.end())
{
//*it += 2;
cout << *it << " ";
++it;
}
cout << endl;
cout << s2 << endl;
auto是可以自动推出it的类型,如果不用auto就需要写string::iterator it,所以auto是方便的,begin可以获取第一个字符的迭代器,如果获取的字符不等于最后一个就一直往后走,直到到\0,
还需要注意*it的it不是指针,在这里作用跟指针差不多,但不是指针,*和++是重载函数有不同与C的作用
4.
// 3、字符赋值,自动迭代,自动判断结束
// 底层就是迭代器
//for (auto ch : s2)
for (auto& ch : s2)
{
cout << ch << " ";
}
cout << endl;
cout << s2 << endl;
ch会从s2的第一个字符开始接收 ,然后执行里面代码,出来重新接收s2的第二个,直到最后一个,自动迭代和自动判断结束,不用自己写,方便。
5.
string s2("hello world");
string::iterator it = s2.begin();
while (it != s2.end())
{
//*it += 2;
cout << *it << " ";
++it;
}
cout << endl;
string::reverse_iterator rit = s2.rbegin();
while (rit != s2.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
首先正常使用迭代器打印s2,接下来就是逆向的迭代器去反着打印元素,需要在原来基础上加上reverse前缀,rend()是第一个元素(与begin区别是begin-1=rend)
6.
const string s3("hello world");
//string::const_iterator cit = s3.begin();
auto cit = s3.begin();
while (cit != s3.end())
{
//*cit += 2;
cout << *cit << " ";
++cit;
}
cout << endl;
//string::const_reverse_iterator rcit = s3.rbegin();
auto rcit = s3.rbegin();
while (rcit != s3.rend())
{
// *rcit += 2;
cout << *rcit << " ";
++rcit;
}
cout << endl;
const为前缀就表示这个是不可修改的,不可修改的是字符串的内容,但是cit可以修改,比如让它指向下一个位置,但是内容是const修饰的, 而它的逆向迭代器再加一个reverse就行。
7.
void TestPushBack()
{
// reverse 反转 逆置
// reserve 保留、预留
string s;
// 提前开空间,避免扩容,提高效率
s.reserve(100);
size_t sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
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';
}
}
}
reserve(100)是确定容量capacity为100,但是出来却不是100是因为整数对齐导致的,g++的就是100,可以看到capacity是没有增加的。注意:但字符串大小小于16或者32是在buf的,大于这个才在堆区上。
4.reserve函数
void test_string4()
{
string s2("hello worldxxxxxxxxxxxxx");
cout << s2.size() << endl;
cout << s2.capacity() << endl << endl;
s2.reserve(20);
cout << s2.size() << endl;
cout << s2.capacity() << endl << endl;
s2.reserve(28);
cout << s2.size() << endl;
cout << s2.capacity() << endl << endl;
s2.reserve(40);
cout << s2.size() << endl;
cout << s2.capacity() << endl << endl;
s2.clear();
cout << s2.size() << endl;
cout << s2.capacity() << endl << endl;
cout << typeid(string::iterator).name() << endl;
cout << typeid(string::reverse_iterator).name() << endl;
}
在vs下若确定的空间小于原来的则不会改变,大于原来的空间才会改变容量
clear函数会清理掉有效的字符,\0会保留,容量空间也会保留
5.范围for
int array[] = { 1,2,3,4,5,6 };
for (auto& e : array)
{
e *= 2;
}
for (auto e : array)
{
cout << e << endl;
}
array的每一个元素会自动赋值给e,先把array的每个元素*2,然后在打印出来