C++奇迹之旅:string类对象的容量操作

发布于:2024-05-08 ⋅ 阅读:(22) ⋅ 点赞:(0)

请添加图片描述


📝 string类的常用接口

string网址查询:https://legacy.cplusplus.com/reference/string/string/

🌉 string类对象的容量操作

在这里插入图片描述

函数名称 功能说明
size(重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty (重点) 检测字符串释放为空串,是返回true,否则返回false
clear (重点) 清空有效字符
reserve (重点) 为字符串预留空间**
resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充

🌠size

  1. size—》返回字符串的长度(以字节为单位)。
size_t size() const;

在这里插入图片描述

string str("hello C++");
cout << "The size of str is " << str.size() << endl;

在这里插入图片描述

🌠length

  1. length—》返回字符串的长度(以字节为单位)
size_t length() const;

在这里插入图片描述

string str2("hello string");
cout << "The lenth of str2 is " << str2.length() << endl;

在这里插入图片描述

string::sizestring::length 是同义词,返回完全相同的值。

🌠capacity

  1. capacity---->返回当前为字符串分配的存储空间的大小,以字节表示。
size_t capacity() const;

在这里插入图片描述
之所以 str.capacity() 的值是 15,是因为 C++ 标准库在创建字符串时会分配一些额外的内存空间来应对未来可能的字符串增长。这个额外的内存空间被称为 “预留空间”。

字符串 "hello C++"10 个字符,但是 C++ 标准库在创建这个字符串时会分配 15 个字符的内存空间。这样可以避免频繁的内存重新分配操作,提高性能,所以 str.capacity() 的值是 15

🌠clear

  1. 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

  1. 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

  1. 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

  1. 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::stringsize()capacity() 函数返回的值都会发生变化。

  1. 将字符串大小设置为 20 个字符,并用字符 'x' 填充新增的部分
string str = "Hello, world!";
str.resize(20, 'x');
cout << str << endl;

在这里插入图片描述

  1. 将字符串大小缩小到 5 个字符:
	string str = "Hello, world!";
	str.resize(20, 'x');
	cout << str << std::endl;

注意:如果 n 小于当前 std::string 的大小,则 resize() 函数会截断字符串,删除超出部分的字符。如果 n 大于当前 std::string 的大小,则 resize() 函数会扩展字符串,并用指定的字符填充新增的部分。
在这里插入图片描述


🚩总结

  1. size()length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一
    致,一般情况下基本都是用size()
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
    请添加图片描述

网站公告

今日签到

点亮在社区的每一天
去签到