认识string(二)详解

目录

  • Capacity
    • size和lenth
    • capacity
      • capacity的扩容机制
    • clear
    • shrink_to_fit(缩容)
    • resize
    • reserve
  • Element access
    • operator[]
    • at

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

Capacity

size和lenth

这两个其实是一样的,我们通常使用的是size

size的英文解释:The number of bytes in the string.size_t is an unsigned integral type (the same as member type string::size_type).
翻译:字符串size_t中的字节数是无符号整数类型(与成员类型string::size_type相同)。

lenth的英文解释:The number of bytes in the string.size_t is an unsigned integral type (the same as member type string::size_type).
翻译:字符串size_t中的字节数是无符号整数类型(与成员类型string::size_type相同)。

int main()
{
	string s1("jackjohn");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	return 0;
}

从这个结果可以看出size和length是没有算上\0的
在这里插入图片描述

capacity

英文解释:The size of the storage capacity currently allocated for the string.size_t is an unsigned integral type (the same as member type string::size_type).
翻译:当前为字符串分配的存储容量的大小。size_t是一个无符号整数类型(与成员类型string::size_type相同)。

我们看看下面的例子

int main()
{
	string s1("jackjohn");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	return 0;
}

在这里插入图片描述

int main()
{
	string s1("jack");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	return 0;
}

在这里插入图片描述

int main()
{
	string s1("jackjohn1111111111");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	return 0;
}

[外链图片转存中...(img-BqPD1V2z-1720796821931)]

从上面的例子可以得出capacity一开始是给定义一块固定的空间的,当超过这个空间的最大容量时,就会扩容,下面我们研究一下这个扩容机制

capacity的扩容机制

int main()
{
	string s1("jackjohn");
	size_t sz = s1.capacity();
	for (int i = 0; i < 100; i++)
	{
		s1.push_back('c');
		if (sz != s1.capacity())
		{
			sz = s1.capacity();
			cout << "capacity changed   " << sz <<endl;
		}
	}
	return 0;
}

这段代码的逻辑就是先让sz记录capacity最开始的值,然后用循环不断的压栈(不断的在jackjohn后面加c),当sz不等于capacity时,就说明已经扩容了,然后将扩容的值打印出来
在这里插入图片描述

因为capacity是没有将\0计算进去的,所以如果加上\0的话,扩容值如下
32 48 71 106 158,我们发现没相临的一次扩容比例是1.5,如果算上第一次扩容前的15的话,就是第一次扩容的比例是2倍关系
这是vs的扩容机制,而在linux环境下的扩容比例是2倍关系

clear

英文解释:Erases the contents of the string, which becomes an empty string (with a length of 0 characters).
翻译:擦除字符串的内容,该字符串将变为空字符串(长度为0个字符)
clear是用来清除数据的,但是空间并不能被清理

int main()
{
	string s1("jackjohn");
	size_t sz = s1.capacity();
	for (int i = 0; i < 100; i++)
	{
		s1.push_back('c');
		if (sz != s1.capacity())
		{
			sz = s1.capacity();
			cout << "capacity changed   " << sz <<endl;
		}
	}
	cout << s1 << endl;
	s1.clear();
	cout << s1 << endl;
	cout << "capacity" << s1.capacity() << endl;
	return 0;
}

在这里插入图片描述

shrink_to_fit(缩容)

shrink_to_fit的功能就是缩容

int main()
{
	string s1("jackjohn");
	size_t sz = s1.capacity();
	for (int i = 0; i < 100; i++)
	{
		s1.push_back('c');
		if (sz != s1.capacity())
		{
			sz = s1.capacity();
			cout << "capacity changed   " << sz <<endl;
		}
	}
	cout << s1 << endl;
	s1.clear();
	cout << s1 << endl;
	cout << "capacity " << s1.capacity() << endl;
	s1.shrink_to_fit();
	cout << "capacity " << s1.capacity() << endl;
	return 0;
}

在这里插入图片描述

resize

resize是改变size,如下图
当size=20,capacity=50的时候(size是有效数据的空间,capacity是开辟出来的空间)
在这里插入图片描述

resize可能会出现下面的三种情况
resize(10),resize(30),resize(60)

resize(10)是让size变到10,而10是小于20的,说明size当中的有效数据需要删除

resize(30)表示让size变到30,而30是大于20且小于50的
size表示的是有效字符数据,既然size增大了,那就应该在之前的字符串中尾插一些字符,让有效数据增大
resize有两种函数void resize (size_t n)和void resize (size_t n, char c);
第一种是size增大时会在字符串中尾插\0
第二种就是尾插给定字符

resize(60)表示让size变到60,但是size已经大于了capacity了,所以需要扩容

我们来验证一下

int main()
{
	string s1("jackjohn");
	size_t sz = s1.capacity();
	cout << s1.size() << " " << s1.capacity() << endl;
	s1.resize(5);
	cout<<s1 << " " << s1.size() << " " << s1.capacity() << endl;
	s1.resize(13,'a');
	cout << s1 << " " << s1.size() << " " << s1.capacity() << endl;
	s1.resize(5);
		cout << s1 << " " << s1.size() << " " << s1.capacity() << endl;
	s1.resize(20);
	cout << s1 << " " << s1.size() << " " << s1.capacity() << endl;
	return 0;
}

[外链图片转存中...(img-sGyWMt48-1720796821935)]

reserve

reserve和reverse这两个需要区别开,reserve的意思是保留,reverse的意思是颠倒
reserve可以理解成提前开好一块空间,因为扩容的时候我们可能会多次扩容,而多次扩容会导致浪费空间,所以如果我们提前开好一块空间的话就会减少扩容次数

int main()
{
	string s1("jackjohn");
	size_t sz = s1.capacity();
	cout << "capacity " << s1.capacity() <<" " << endl;
	s1.reserve(100);
	cout << "capacity " << s1.capacity() <<" " << endl;
	s1.reserve(10);
	cout << "capacity " << s1.capacity() << " " << endl;
	s1.reserve(120);
	cout << "capacity " << s1.capacity() << " " << endl;
	return 0;
}

[外链图片转存中...(img-qHGM2Y6M-1720796821936)]

而根据上面的结果可以看出reserve可以用于扩容和缩容,而我们发现我们要扩容到100的时候,capacity是111,而缩容到10的时候capacity是15,说明reverse并不完全按照我们给定的数字开空间

Element access

operator[]

英文解释:The character at the specified position in the string.If the string object is const-qualified, the function returns a const char&. Otherwise, it returns a char&.

翻译:字符串中指定位置的字符。如果字符串对象是const限定的,那么函数将返回一个const char&。否则,它将返回一个char&

operator[]有两个函数 char& operator[] (size_t pos)和const char& operator[] (size_t pos) const
const修饰的表示只能读不能写,也就是传入参数后我们不能通过这个函数去修改传参的值

int main()
{
	string s1("jackjohn");
	cout << s1[5] << endl;
	return 0;
}

[外链图片转存中...(img-UVElECgA-1720796821937)]

at

英文解释:The character at the specified position in the string.If the string object is const-qualified, the function returns a const char&. Otherwise, it returns a char&.

翻译:字符串中指定位置的字符。如果字符串对象是const限定的,那么函数将返回一个const char&。否则,它将返回一个char&。

at也是有两个函数 char& at (size_t pos)和const char& at (size_t pos) const

int main()
{
	string s1("jackjohn");
	cout << s1.at(5) << endl;
	return 0;
}

[外链图片转存中...(img-8YL6hSxS-1720796821937)]

看起来at和operator[]没有区别,实际上他们的区别是在越界的报错

在这里插入图片描述
在这里插入图片描述

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值