首页 > 其他分享 >STL.string(上)

STL.string(上)

时间:2024-10-14 22:50:05浏览次数:9  
标签:capacity string 16 STL 空间 resize size

string


由于string创始初期没有参照导致的冗余问题,这里没办法完全的进行的总结,所以只会列出一些常用的。

string类

string是表示字符串的字符串类
在这里插入图片描述
这里出现这么多不同的string的原因是编码表的不同。string => UTF-8、u16string => UTF-16、u32string => UTF-32。
该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
不能操作多字节或者变长字符的序列。
在这里插入图片描述

string类构造

在这里插入图片描述

int main()
{
	string s1;//默认构造1
	string s2("hello world!");//拷贝构造2
	string s3 = "hello world!";//const char*隐式类型转换为string 先构造再拷贝构造被优化成拷贝构造  4
	string s4(s3, 6, 3);//substring 3
	cout << s4 << endl;
	string s5(s3, 6, 13);//太少的话取到末尾
	cout << s5 << endl;
	string s6(s3, 6);//不给的话,自动赋值-1,32亿9千万,极值
	cout << s6 << endl;
	string s7(s2, 3);//对s2的第三个字符开始向后复制 5
	string s8(5,'x');//在s8中填充5个x 6
	
}

在这里插入图片描述

string类对象的容量操作

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

size和length

size 和length 功能是重叠的,原因是string过早,有些冗余。一般都使用size!
在这里插入图片描述

max_size

极值跟系统资源有关系,所以并没有什么实际用处。
在这里插入图片描述

append

添加进入一个字符串,一般不用push_back 和append ,而是使用 operator+= 。

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

小总结下size、capacity、append、operator+=

在string尾部追加字符时,s.push_back( c ) / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

int main()
{
	string s1("hello world");
	cout << s1.size() << endl;
	cout << s1.length() << endl;//俩者并无差别,发展历程length先出现
	cout << s1.max_size() << endl;//最大申请数量,意义不大
	cout << s1.capacity() << endl;//实际上是16字符,但是\0不计入

	s1.push_back(' ');
	s1.push_back('!');
	cout << s1 << endl;

	s1.append("yes");
	cout << s1 << endl;
	cout << "_______________________" << endl;
	s1 += ' ';
	s1 += '!';
	s1 += "yesyes";//实际我们使用+=多一点
	cout << s1 << endl;
	return 0;
}

在这里插入图片描述

这里需要注意s1.capacity是15个字节,但是后面是有一个’\0’,capacity并没有将’\0’算入其中,所以实际上是16个字节。
至于为什么是16字节,这与编译器的底层逻辑相关,不同编译器的大小不同,在后面附录1会详细讲。

resize

在这里插入图片描述

resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_tn, char c)用字符c来填充多出的元素空间。
注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

resize 是 扩容+初始化,如果数量比size小,那么会删除数据,但是不会修改capacity!
因为缩容是不支持原地缩容,都是异地缩容,由于缩容需要释放空间,所以会先开辟新空间,然后拷贝,再释放空间,会产生很大的资源消耗,所以一般不会进行缩容

 int main()
{
	// 扩容
	string s1("hello world");
	s1.reserve(100);
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

	// 扩容+初始化
	string s2("hello world");
	s2.resize(100, 'x');
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;

	// 比size小,删除数据,保留前5个
	s2.resize(5);//缩容,但是不建议使用缩容,因为缩容是异地缩容
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;

	return 0;
}

在这里插入图片描述

reserve

在这里插入图片描述

前提:知道需要多少空间,可以帮助我们提前开空间,减少扩容,提升效率。

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

int main()
{
	// 观察扩容情况  -- 1.5倍扩容
	string s;
	size_t sz = s.capacity();
	cout << "making s grow:\n";
	cout << "capacity changed: " << sz << '\n';
	for (int i = 0; i < 100; ++i)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

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

初识迭代器

在这里插入图片描述

附录

1. vs下string结构的说明(解释前文为什么capacity是16而不是别的)

vs下string的结构
string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:
当字符串长度小于16时,使用内部固定的字符数组来存放
当字符串长度大于等于16时,从堆上开辟空间

class string//猜测是这样子的
{
private:
	char* _ptr;//如果小于16字节,那么存在在_buf中,但如果大于就会用_ptr指堆开辟的空间
	char _buf[16];
	size_t _size;
	size_t _capacity;
};

在这里插入图片描述
一个指针+16字节空间+1个size_t字段保存字符串长度+1个size_t字段保存从堆上开辟空间总的容量
4+16+4+4=28
在这里插入图片描述

标签:capacity,string,16,STL,空间,resize,size
From: https://blog.csdn.net/weixin_67466860/article/details/137299808

相关文章

  • String常用类
    String​(byte[] bytes,int offset,int length)通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。  String​(byte[] bytes,int offset,int length,String charsetName)通过使用指定的字符集解码指定的字节子String构造新的St......
  • 【标准库中的string类】
    【知识预告】string类的常用接口说明string类对象的访问及遍历操作string类对象的容量操作string类对象的修改操作相关例题1string类的常用接口说明(只写了常用的)千言万语都不如来段代码直接intmain(){ strings1; strings2("hello"); cin>>s1; cout<<s1<<......
  • STL——string类的模拟实现
    一.STL简介 1.1什么是STL STL(standardtemplatelibaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。1.2STL的六大组件接下来开始模拟实现STL中的常用string类三个成员变量char*......
  • StringUtils Java字符串工具类
    在我们的代码中经常需要对字符串判空,截取字符串、转换大小写、分隔字符串、比较字符串、拼接字符串、使用正则表达式等等。如果只用String类提供的那些方法,我们需要手写大量的额外代码,不然容易出现各种异常。现在有个好消息是:org.apache.commons.lang3包下的StringUtils工......
  • 【C++】list(STL)
    list的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于......
  • Java【String类】
    字符串的本质是字符数组,是由字母、数字、汉字、下划线组成的一串字符。在Java中字符串属于对象。字符串是常量,内容用双引号括起来,在创建之后不能更改,但是可以使用其他变量重新赋值的方法进行更改。目录1.String类创建方式1.1直接创建1.2用new关键字创建2.String类的A......
  • C++STL~~map
    文章目录序列式容器和关联式容器一、map的概念二、map的使用三、map&multimap的差异四、map的练习五、总结序列式容器和关联式容器序列式容器前面已经接触过STL中的部分容器如:string、vector、list、deque、array、forward_list等,这些容器统称为序列式容器,因为逻辑......
  • C++ 非STL数据结构学习——1.4 字典树
    1.字典树的定义字典树是一种多叉树结构,每个节点代表一个字符,从根节点到某个节点的路径表示一个字符串。每个节点包含若干指向子节点的指针,通常使用数组、哈希表或其他数据结构来实现。2.字典树的基本操作插入:将一个字符串插入到字典树中。查找:在字典树中查找一个字符串是否......
  • 【STL】vector的介绍及使用
    文章目录目录文章目录前言二、vector常用接口的使用1.vector的定义2.vectoriterator的使用3.vector空间增长问题4.vector的增删查改find函数5.迭代器失效问题......
  • STL 容器用法简要整理(未完成)
    STL容器用法简要整理本文将简要介绍C++14中可以使用的STL容器的用法。根据CCF规定,这些容器都可以在比赛中使用。本文中的代码均为C++14。本文中的代码均已引入了相关的库,并usingnamespacestd。共同点特性:所有能用下标访问的STL容器,下标都是从0开始,到size-......