文章目录
- 📝 string类的常用接口
- 🌉 string类对象的容量操作
- 🌠size
- 🌠length
- 🌠capacity
- 🌠clear
- 🌠empty
- 🌠reserve
- 🌉resize
- 🚩总结
📝 string类的常用接口
string
网址查询:https://legacy.cplusplus.com/reference/string/string/
🌉 string类对象的容量操作
函数名称 | 功能说明 |
---|---|
size(重点) | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
capacity | 返回空间总大小 |
empty (重点) | 检测字符串释放为空串,是返回true ,否则返回false |
clear (重点) | 清空有效字符 |
reserve (重点) | 为字符串预留空间** |
resize (重点) | 将有效字符的个数该成n 个,多出的空间用字符c 填充 |
🌠size
size
—》返回字符串的长度(以字节为单位)。
size_t size() const;
string str("hello C++");
cout << "The size of str is " << str.size() << endl;
🌠length
length
—》返回字符串的长度(以字节为单位)
size_t length() const;
string str2("hello string");
cout << "The lenth of str2 is " << str2.length() << endl;
string::size
和string::length
是同义词,返回完全相同的值。
🌠capacity
capacity
---->返回当前为字符串分配的存储空间的大小,以字节表示。
size_t capacity() const;
之所以 str.capacity()
的值是 15
,是因为 C++
标准库在创建字符串时会分配一些额外的内存空间来应对未来可能的字符串增长。这个额外的内存空间被称为 “预留空间”。
字符串 "hello C++"
有 10
个字符,但是 C++
标准库在创建这个字符串时会分配 15
个字符的内存空间。这样可以避免频繁的内存重新分配操作,提高性能,所以 str.capacity()
的值是 15
。
🌠clear
clear
–》擦除字符串的内容,该字符串将变为空字符串(长度为 0 个字符)。
void clear();
clear
擦除字符串的内容,该字符串将变为空字符串,长度为0
,但是存储空间没有改变
int main()
{
string s1("hello C++");
cout << s1 << endl;
s1.clear();
cout << s1 << endl;
cout << s1.size() << endl;
cout << s1.capacity() << endl;
return 0;
}
🌠empty
empty
–》返回字符串是否为空(即其长度是否为 0)
此函数不会以任何方式修改字符串的值。若要清除字符串的内容,请看string::clear
。
bool empty() const;
如果字符串长度为 0
,则为 true
,否则为 false
。
int main()
{
string str1;// 创建一个空字符串
string str2 = "Hello, world!"; // 创建一个非空字符串
if (str1.empty())
{
cout << "str1 is empty." << endl;
}
else
{
cout << "str1 is not empty." << endl;
}
if (str2.empty())
{
std::cout << "str2 is empty." << std::endl;
}
else {
std::cout << "str2 is not empty." << std::endl;
}
return 0;
}
🌠reserve
reserve
—》为字符串预留空间
std::string::reserve()
是std::string
类的一个成员函数,用于预先分配内存空间,以提高字符串的性能。
当你需要向字符串中添加大量字符时,使用 reserve()
函数可以避免频繁的内存分配和拷贝操作,从而提高程序的性能。
int main()
{
string str;
//不使用reserve
for (int i = 0; i < 1000000; i++)
{
str += 'a';
}
cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;
//使用reserve()
string str2;
str2.reserve(1000000);
for (int i = 0; i < 1000000; i++)
{
str2 += 'a';
}
cout << "size: " << str2.size() << ",Capacity: " << str2.capacity() << endl;
return 0;
}
可以看到,在使用 reserve()
函数的情况下,str2
的容量(capacity)
与大小(size)
相同,而在不使用 reserve()
函数的情况下,str
的容量大于其大小。这就是 reserve()
函数的作用:它可以预先分配内存空间,避免频繁的内存分配和拷贝操作,从而提高程序的性能。
str2.reserve(10);//容量不足会怎么样?
当你将
str2.reserve(10)
设置的容量远小于实际需要的容量,输出结果也会显示Capacity: 1170118
。这是因为std::string
的内部实现机制。
当你使用reserve()
函数时,它会尝试分配指定大小的内存空间。但是,如果实际需要的空间大于指定的空间,std::string
会自动增加内存空间,以满足实际需求。这个过程称为"内存重新分配"。
即使只预留了10
个字符的空间,但当你向str2
添加1,000,000
个字符时,std::string
会自动增加内存空间,以容纳所有的字符。这就是为什么最终的容量会大于1,000,000
的原因。
std::string
的容量通常会比实际需要的空间大一些,这是为了提高性能。当需要添加新的字符时,不需要频繁地重新分配内存,从而避免了内存拷贝的开销。
- 增长策略:
当向std::string
添加字符时,如果当前容量不足,标准库会自动分配一个更大的内存块。增长策略通常是以当前容量的2
倍或1.5
倍来扩展容量,以减少内存重新分配的次数。
//利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBack()
{
string s;
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';
}
}
}
- 构建
vector
时,如果提前已经知道string
中大概要放多少个元素,可以提前将string
中空间设置好
void TestPushBackReserve()
{
string s;
s.reserve(100);
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';
}
}
}
🌉resize
resize
—》用来改变std::string
对象的大小
两种语法:
void resize (size_t n);
void resize (size_t n, char c);
- 第一种形式的
resize()
函数会将std::string
的大小设置为n
个字符,并用默认值 (通常是'\0'
) 填充新增的字符。
void resize (size_t n);
例子:
string str = "Hello, world!";
cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;
str.resize(20);
cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;
可以看出:与 reserve()
函数不同,resize()
函数不仅改变了 std::string
的容量,还改变了它的大小。这意味着,调用 resize()
函数后,std::string
的 size()
和 capacity()
函数返回的值都会发生变化。
- 将字符串大小设置为
20
个字符,并用字符'x'
填充新增的部分
string str = "Hello, world!";
str.resize(20, 'x');
cout << str << endl;
- 将字符串大小缩小到 5 个字符:
string str = "Hello, world!";
str.resize(20, 'x');
cout << str << std::endl;
注意:如果
n
小于当前std::string
的大小,则resize()
函数会截断字符串,删除超出部分的字符。如果n
大于当前std::string
的大小,则resize()
函数会扩展字符串,并用指定的字符填充新增的部分。
🚩总结
size()
与length()
方法底层实现原理完全相同,引入size()
的原因是为了与其他容器的接口保持一
致,一般情况下基本都是用size()
。clear()
只是将string
中有效字符清空,不改变底层空间大小。