2024年最全【C++】STL —(1),C C++开发手册

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

🌈欢迎来到C++专栏~~String类(万字详解)


  • (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort🎓
  • 🌍博客主页:张小姐的猫~江湖背景
  • 快上车🚘,握好方向盘跟我有一起打天下嘞!
  • 送给自己的一句鸡汤🤔:
  • 🔥真正的大师永远怀着一颗学徒的心
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
  • 🎉🎉欢迎持续关注!
    在这里插入图片描述

请添加图片描述

本文目标

请添加图片描述

学习STL要多翻阅官方文档 cplusplus.com,话不多说,发车

一. 编码科普

为什么string不能针对char来写?因为编码不同。char只能表示256个字符。
所以这时候要用模板。

string管理的是一个char*的字符串。
u16string:一个字符是两个字节
u32string:一个字符是四个字节
wstring:叫做宽字符,一个字符占两个字节

🐋ASCII码

ASCII码表。是美国设计的。
ASCII码表是:计算机当中存的值,和字符的映射
但是只有256个字符的表示。用char表示

🐋Unicode

也叫做万国码

Unicode是针对全世界的语言而设计的一种编码。

常见的有utf-8 utf-16 utf-32

🐋gbk

gbk是叫做国标码。是针对中文创建的一个编码。其中还涉及台湾的繁体字。

计算机上不止有英文,还要有中文,日文等语言。但是ASCII码表不足以表示

二. String类

string类实际上是basic_string这个类模板的实例化 ——
在这里插入图片描述

其底层实现大概如下:

template<class T>
class basic\_string
{
	// ...
private:
	T\* _str; //动态申请的
    size_t _size;
    size_t _capacity;
	// ...
};

我们发现字符串类型不仅仅只有字符串,为什么还会有类模板呢?这就涉及到不同编码规则问题

ascii编码表(老美写的)中,将值和符号建立映射关系,1byte空间可以表示256个英文字符;再说unicode,是为了表示全世界文字的编码表,其中的utf-16方案,所有字符,无论中英还是啥,都是两字节表示。我们认识到的,字符可不简单的是char,还可以是wchar宽字符等等

🔥下面介绍string类常用的接口 ,要熟练掌握,其余的用时查阅即可。在使用string类时,需要包含头文件#include<string>以及展开命名空间using namespace std;

三.构造 & 析构 & 赋值重载

⚡构造函数

在这里插入图片描述

展示:——
在这里插入图片描述这里我们看见是一个空串,但是为了更好的兼容c,它后面是给了一个\0的,我在原始视图里发现

在这里插入图片描述
说明符合c字符串的规范

其余的接口简单演示,主要为了演示如何查阅文档

功能:从pos开始取对象的一部分(len)。

substring (3)	string (const string& str, size_t pos, size_t len = npos);

其中len给了缺省值npos,npos是string类的一个静态成员变量,值为-1,换算成补码就是全1,赋值给了size_t,也就是整型的最大值4,294,967,295。那如果不传参数的话,基本上是有多少取多少。

在这里插入图片描述
在这里插入图片描述
注:string类对象支持直接用cin和cout进行输入和输出,因为重载了流插入>>和流提取<<操作符(后面说)

取字符串前n个(用的非常少)

from sequence (5)	string (const char\* s, size_t n);

在这里插入图片描述
⚡ 一键初始化

fill (6)	string (size_t n, char c);

在这里插入图片描述

⚡析构函数(不重要)

析构我们不管,对象出了作用域,自动调用的

⚡赋值重载

在这里插入图片描述

string s1;
string s2 = "hello world";//构造+拷贝构造-》优化——直接构造

s1 = s2;
s1 = "xxxxx";
s1 = 'y';

如果现在让我们取实现逆置一个字符串,我们又不能拿的到str(私有),何况我们都不知道底层是_str 还是str_ ,不清楚底层实现,这就要引出[]

四.operator[ ]

重载了[],使得string类可以像数组一样访问字符。不同的是,数组访问本质是解引用,而这里是调用函数。

它提供了两个版本 ——

在这里插入图片描述

其大概的底层实现如下:

char& operator[](size_t pos)//传引用返回,别名
{
   assert(pos<_size);
   return _str[pos];
}

operator[]传引用返回,返回的是别名,这使得它可读可写

这里不是为了减少拷贝,而是为了做输出型参数,支持修改返回值

在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string s("more than words");
	// 1.可读
	//for (size\_t i = 0; i < s.length(); i++) 二者都是求长度,string比较早,且不适合一些树的结构
	for (size_t i = 0; i < s.size(); i++)
	{
		//等价于cout << s.operator[](i) << " " <<; 
		cout << s[i] << ' ' ;
	}
	cout << endl;
    
	// 2.可写
	for (size_t i = 0; i < s.size(); i++)
	{
		s[i] += 1;
	}
	cout << s << endl;
	return 0;
}

在这里插入图片描述对于const修饰的就不能修改了

const string s2("hello world");
for (size_t i = 0; i < s1.size(); ++i)
{
	s2[i]++;//报错了
}

下面两个函数功能一致,(at的存在有历史原因)只不过二者检查越界的方式不同,推荐使用[] ——

在这里插入图片描述

五、Capacity 容量操作

在这里插入图片描述

⚡size vs length

➰字符串中有效字符长度,即不包含最后作为结尾标识符的\0

在这里插入图片描述

两者底层实现完全一致(length的存在是历史原因),但强烈推荐使用size. 这是为了和后序各种容器接口保持一致(二叉树你不能用length吧)

capacity

容量:能存多少个有效字符(注意\0无效字符不算),要记得string类的底层是顺序表结构,初始值是15

在这里插入图片描述

⚡resize vs reverse

reserveresize 都是改变容量,申请至少n个字符的空间(字符串涉及对齐问题,后续详谈) ,但有所不同 ——

🤞1. resize - 开空间,并可以对空间初始化

在这里插入图片描述
翻译知道

  • 如果是将元素个数减少,会把多出size的字符抹去,这不挺resize的吗(狗头)
  • 如果是将元素个数增多,void resize (size_t n);,用\0来填充多出的元素空间,void resize (size_t n, char c);字符c来填充多出的元素空间
  • 注:resize在改变元素个数时,如果是将元素个数增多,可能会改变容量的大小;如果是将元素个数size减少,容量不变
void test\_string14()
{
	string s1("JDG 总冠军");
	s1.resize(5);//size缩小成5,capacity不变

	string s2("JDG 总冠军");
	s2.resize(100);//填充'\0',size——>100,capacity->111(自动扩容)

	string s3("JDG 总冠军");
	s3.resize(100,'~');//填充'\0',size——>100,capacity->111(自动扩容)
}

➰ 2. reserve - 开空间。在已知需要多少空间时,调用reserve,可以避免频繁增容的消耗

在这里插入图片描述

  • 为字符串预留空间改变容量。当然了不会改变有效元素个数size
  • 给reserve的参数n小于string的容量时,是无效请求,并不会改变容量大小
#include<string>

using namespace std;

int main()
{
	string s1;
	s1.reserve(100); // size - 0,capcacity->111

	string s2("more than words");
	s2.reserve(5);   // capacity和size仍为15

	return 0;
}

⚡clear

清空有效字符,容量不变
在这里插入图片描述

⚡empty

检测字符串是否为空串

在这里插入图片描述

六、iterator 迭代器

第二种遍历的方法:迭代器,对于string类,无论正着还是倒着走,[下标]的方法都足够好用,为什么还要有迭代器?
🤞🤞事实上,迭代器是一种通用的遍历方式,且用法类似所有容器都可以使用迭代器这种方式去访问修改,而list、map/set不支持[下标]遍历。结论是,对于string类,我们得会用迭代器,但是我们更喜欢用[下标]

🌈正向迭代器

正向迭代器提供了两个函数——
在这里插入图片描述

在这里插入图片描述

🌈迭代器 iterator是指针一样的类型,不确定是不是(薛定谔的猫),但它的用法像指针一样, 其区间[ }左闭右开

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string s("more than words");
	// 1.可读
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << \*it << " ";
		it++;
	}
	cout << endl;

	// 2.可写
	it = s.begin();
	while (it != s.end())
	{
		\*it += 1;
		it++;
	}
	cout << s <<endl;
	return 0;
}

在这里插入图片描述

  • iterator依然提供了两个版本,第二个是const变量
  • 关于遍历的时候!=能不能改成<= ,可以但是没必要,因为在string的物理空间是连续的,其他容器list等不一定连续。
🌈反向迭代器

也提供了两个成员函数

在这里插入图片描述

在这里插入图片描述

void test\_string5()
{
	string s("hello");
	string::reverse_iterator rit = s.rbegin();
	//auto rit = s.rbegin();//auto 可以自动推导类型
	while (rit != s.rend())
	{
		cout << \*rit << " ";
		rit++;
	}
	cout << endl;
}

在这里插入图片描述

🌈const迭代器

所谓的const迭代器就是针对const的版本嘛

  • 普通迭代器可读可写,相当于string类模板中,类型为T*
  • 而const迭代器不可写。这是因为是const成员函数,const修饰this指针指向的内容(相当于string类模板中,类型为const T*)

const迭代器也分正向迭代器反向迭代器,且就是给const对象用的。这是因为const对象才能调用这里的const成员函数,返回const迭代器,不可写。

在这里插入图片描述
使用情况如下:

void test\_string6()
{
	string s("hello");
	// const正向迭代器 - 可读不可写
	string::const_iterator it = s.begin();
	while (it != s.end())
	{
		cout << \*it << " ";
		it++;
	}
	cout << endl;

	// const反向迭代器 - 可读不可写
	string::const_reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << \*rit << " ";
		rit++;
	}
	cout << endl;
}

传参进func中,s是const对象,自动调用第二个接口,返回的是const_iterator,要用const迭代器类型接收,且不能修改

在这里插入图片描述

C++11为了区分const迭代器和普通迭代器还提供了以下接口,不然调用时容易混淆

在这里插入图片描述

🌈范围for遍历

范围for是C++11提供的语法糖🍬,实际上底层编译器会替换成迭代器(反汇编里可以看出) 只能正向遍历

🍬依次取s中的每个字符,赋值给ch

  • 自动迭代
  • 自动判断结束
#include<iostream>
#include<string>

using namespace std;

int main()
{
	string s("more than words");
	for (auto& ch : s)
	{
		cout << ch << " ";
	}
	cout << endl;

	for (auto& ch : s)
	{
		ch += 1;
	}
	cout << s << endl;
	return 0;
}

ps:

  • 若要修改,auto要加上&。因为*it会依次赋值给chch是*it的拷贝,*it改变不影响ch,所以要加上&

七、Modifiers 修改

🎨追加

在这里插入图片描述

+=最好用也最常用,因为既可以追加字符、也可追加字符串 ,其实底层调用了appendpush_back

void test\_string7()
{
	string s("hello");
	s.push\_back('-');
	s.push\_back('-');
	s.append("world");
	cout << s << endl;

	string str("我来了");
	s += '@';//字符
	s += str;//字符串
	s += "JDG总冠军";
	cout << s << endl;
}

在这里插入图片描述
其中append的迭代器可以选择性的打印字符串内容(了解即可)

string s("hello");
string str("我来了");

s.append(++str.begin(), --str.end());
string copy(s.begin() + 5, s.end() -5);

在这里插入图片描述

下面来研究尾插扩容容量变化 ——

void test\_string8()
{
	string s;
	size_t sz = s.capacity();
	cout << "making s grow:\n";
	for (int i = 0; i < 100; ++i)


![img](https://img-blog.csdnimg.cn/img_convert/b8e4a3937f12161a5969d5e2572d349b.png)
![img](https://img-blog.csdnimg.cn/img_convert/a19630d520676cba0acedf4e99c006ce.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

符串内容(了解即可)



string s(“hello”);
string str(“我来了”);

s.append(++str.begin(), --str.end());
string copy(s.begin() + 5, s.end() -5);


![在这里插入图片描述](https://img-blog.csdnimg.cn/20743bf8af1044c893e3425c24925852.png)


下面来研究尾插扩容容量变化 ——



void test_string8()
{
string s;
size_t sz = s.capacity();
cout << “making s grow:\n”;
for (int i = 0; i < 100; ++i)

[外链图片转存中…(img-LwDyObrn-1715755687850)]
[外链图片转存中…(img-XcvA9U5T-1715755687851)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值