文章目录
- String常用的接口(黑框标记的是常用接口)
- string类对象的反向遍历操作
- 第一种
- 第二种
 
- 容量
- string的扩容机制
 
 
String常用的接口(黑框标记的是常用接口)
string类对象的反向遍历操作
第一种
通过下表进行遍历
void TestString1()
{string s1("hello world");for (int i = s1.size(); i >= 0; i--){cout << s1[i] << " ";}cout << endl;
}
第二种

- reverse_iterator:
 反向迭代器

- rbegin:
 返回一个指向字符串最后一个字符的反向迭代器(即它的结尾)。

- rend:
 返回一个反向迭代器,指向字符串第一个字符前面的理论元素(该元素被认为是字符串的反向结束)。
void TestString2()
{string s1("hello world");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()){cout << *rit << " ";rit++;}cout << endl;
}
容量

- szie:
 返回字符串的长度,以字节为单位。

- lenth:
 返回字符串的长度,以字节为单位。
void TestString3()
{string s1("hello world");cout << s1.size() << endl;cout << s1.length() << endl;
}

 没错你没有理解错,这两个接口作用完全一样,都是表示字符串中的字符数量。
 至于原因:
 主要是为了保持与C风格字符串处理函数的兼容性,因为在C语言中,字符串的长度是通过 strlen() 函数得到的,它返回的是字符串中的字符数量,不包括结尾的空字符 \0。简而言之就是为了保持与C语言字符串处理函数的一致性。

- max_size:
 返回字符串可以达到的最大长度。
void TestString4()
{string s1("hello world");cout << s1.max_size() << endl;
}
注:
 max_size的值取决于实现和系统资源。不同编译器或者不同平台的实现可能会有所不同

- capacity:
 返回当前为字符串分配的存储空间的大小,以字节表示
void TestString5()
{string s1("hello world");cout << s1.capacity() << endl;
}
说到string的分配储存空间,就说一下string的扩容机制
string的扩容机制
首先我们看下main的代码:
void Viewcapacity()
{string s;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';}}
}

 我们可以看出第一次扩容是二倍扩容[ capacity是没包含‘\0’的,15+‘\0’=16 -> 31+‘\0’=32]
 而之后都是1.5倍扩容
有意思的是在Linux下是这种情况:
 
 我们可以看到是一直二倍进行扩容
在不同的操作系统和编译器下可能会有所不同,这主要是因为底层的内存分配策略和系统资源限制不同。
 其实STL是一个规范,规范功能,没有规定实现细节

- clear:
 清除字符串的内容,使其成为一个空字符串(长度为0个字符)。
void TestString6()
{string s1("hello world");cout << s1 << endl;cout << "capacity:" << s1.capacity() << endl;s1.clear();cout << s1 << endl;cout << "capacity:" << s1.capacity() << endl;
}

 我们可以看出clear可以清除数据但是并没有销毁空间
那么有没有销毁空间的接口呢?
 在C++11中新增了个这个接口:
 
- shrink_to_fit:
 请求字符串减少其容量以适合其大小,就是缩容
那么
void TestString6()
{string s1("hello world xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");cout << s1 << endl;cout << "capacity:" << s1.capacity() << endl;s1.clear();cout << s1 << endl;cout << "capacity:" << s1.capacity() << endl;s1.shrink_to_fit();cout << s1 << endl;cout << "capacity:" << s1.capacity() << endl;
}

 可见capacity缩小,之所以这样(hello world后面全是x)是因为我们现在可以理解为shrink_to_fit缩不到0,至于原因简单来说:shrink_to_fit 函数的作用是让 std::string 的容量(也就是它最多能装多少字符)缩小到刚好能装下它当前有的字符数量。如果 std::string 里面有15个字符,那么调用 shrink_to_fit 后,它的容量就会缩小到刚好能装下这15个字符的大小。这样做可以节省内存,因为不再需要多余的空间来装更多的字符了。

- reserve:
 请求更改容量请求将字符串容量调整为最多n个字符的计划大小更改,说白了就是扩容
 详细来说:- reserve()是- std::string类的一个成员函数,它的作用是预先分配足够的内存空间,以便将来可以存储更多的字符,而不需要频繁地重新分配内存。当你知道- std::string将会增长到一定的大小时,你可以使用- reserve()来提前分配足够的空间。这样做可以减少内存分配的次数,提高程序的效率,因为频繁的内存分配和释放可能会导致性能下降。
void TestString7()
{string s1;s1.reserve(100);cout << "capacity:" << s1.capacity() << endl;
}

 诶,我明明是开100个空间为什么是111?
 这和扩容机制类似虽然reserve(100) 这个函数调用告诉 std::string 对象预先分配至少100个字符的空间。但是,std::string 的实际容量可能会比100大这也是因为底层的内存分配策略和系统资源限制不同。
 注:reserve只能扩容,比capacity大才会起作用反之不会起作用

- resize:
 将字符串的大小调整为n个字符的长度
 当你调用 resize(n) 时,字符串的大小会被设置为 n ,并且如果字符串当前大小小于 n ,那么会在字符串末尾添加额外的空字符(‘\0’)来填充到新的大小。如果字符串当前大小已经大于或等于 n ,那么 resize() 会截断字符串,只保留前 n 个字符。
那么我们会有这三种情况:
 1.n比size小(如图中插入10)
 2.n比size大但是比capacity小(如图中插入20)
 3.n比capacity还要大(如图中插入30)
 