[C++初阶]string类

1. 为什么要学习string

1.1 C语言中的字符串

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP(面向对象)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。

2. 标准库中的string

2.1 string类的了解

string类的文档介绍
1. 字符串是表示字符序列的类
2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
总结:
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。
使用string类时,必须包含#include头文件以及using namespace std;

2.2 string类的常用接口说明

我们看string类的文档可以发现

有以下几种接口:

内容选自:string::string - C++ Reference (cplusplus.com)

2.2.1 string()  ---- 无参构造函数

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s;
	cout << s <<endl;

	return 0;
}

运行结果:


2.2.2 string (const string& str)-----复制构造函数

代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");
	string s1(s);
	cout << s << endl;
	cout << s1 << endl;

	return 0;
}

运行结果:

2.2.3 string(const string& str, size_t pos, size_t len = npos);----复制从字符位置 pos 开始并跨越 len 字符的 str 部分(如果任一 str 太短或 len 为 string::npos,则复制 str 的末尾)

代码示例:

运行结果:

2.2.4 string(const char*)---- 用char*构造函数

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("Iamchineseperson");
	cout << s << endl;

	return 0;
}

2.3 string对象的容量操作

2.3.1size函数

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");

	cout << s.size() << endl;

	return 0;
}

运行结果:

2.3.2 length函数

返回字符串有效字符长度 size() 与 length() 方法底层实现原理完全相同, 引入 size() 的原因是为了与其他容器的接口保持一致, 一般情况下基本都是用 size()。

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s("Iamchineseprson");

	cout << s.length() << endl;

	return 0;
}

2.3.3 capacity函数

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");

	cout << s.capacity() << endl;

	return 0;
}

运行结果:

2.3.4 empty函数

检测字符串释放为空串,是返回true,否则返回false

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("Iamchineseprson");
	string s2;
	cout << s1.empty() << endl;
	cout << s2.empty() << endl;

	return 0;
}

运行结果:

2.3.5 clear函数

clear()清空有效字符

clear()只是将string中有效字符清空,不改变底层空间大小。

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s("Iamchineseprson");

	cout << s.length() << endl;

	s.clear();

	cout << s.length() << endl;

	return 0;
}

运行结果:

2.3.6 reserve函数

作用:为字符串预留空间
写法:reserve(size_t res_arg=0):
特点:为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量小。

代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");
	cout << s.capacity() << endl;
	s.reserve(30);
	cout << s.capacity() << endl;
	return 0;
}

运行结果:

2.3.7 resize函数

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

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");
	cout << s << endl;
	s.resize(30,'L');
	cout << s << endl;
	return 0;
}

运行结果:

2.4 string对象的访问及遍历接口

//迭代器
string::iterator being();//返回第一个位置的迭代器
string::iterator end();//返回结束位置下一个位置的迭代器
reverse_iterator rbeign();//返回结束位置的迭代器
reverse_iterator rend();//返回开始的前一个位置的迭代器

//at访问位置的值
char& at (size_t pos);	//返回pos位置的值
const char& at (size_t pos) const;	//返回const修饰的pos位置的位置的值

//重载 [] 
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const; 

2.4.1 operator[]

作用:返回pos位置的字符,const string对象调用

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");
	for (int i = 0; i < s.size(); i++)
	{
		printf("[%d] : %c\n", i, s[i]);
	}
	cout << endl;
	return 0;
}

运行结果:

2.4.2 迭代器 begin 、end

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("Iamchineseprson");
	string::iterator it = s.begin();
	while (it < s.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	return 0;
}

运行结果:

2.4.3 迭代器 rbegin 、rend

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseprson");

	string::reverse_iterator it = s.rbegin();
	while (it != s.rend())
	{
		cout << *it << ' ';
		it++;
	}

	cout << endl;

	return 0;
}

运行结果:

2.4.4 at

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseprson");
	for (int i = 0; i < s.size(); i++)
	{
		cout << s.at(i) << " ";
	}
	cout << endl;
	cout << endl;

	return 0;
}

运行结果:

2.4.5 范围for

这里是遍历,自然我们也能用前面学习的范围for

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseperson");

	for (const char ch : s)
	{
		cout << ch << ' ';
	}

	cout << endl;

	return 0;
}

运行结果:

但这里ch的类型是char,我们可能吃不准,所以,很多时候我们都会选择用auto类型

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseperson");

	for (auto ch : s)
	{
		cout << ch << ' ';
	}

	cout << endl;

	return 0;
}

2.5 string的增删查改

1.增

1.连接

(1)函数原型:

//重载 +=
string& operator+= (const string& str);	//在结尾处连接字符串str
string& operator+= (const char* s);		//在结尾处连接字符串s
string& operator+= (char c);			//在结尾处连接字符c

//append 在字符串结尾连接	
string& append (const string& str);	//在结尾处连接字符串str
string& append (const char* s);	//在结尾处连接字符串s
//连接从迭代器first 到 last 这个区间到结尾 左闭右开
template <class InputIterator>	
string& append (InputIterator first, InputIterator last);


#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseperson");

	s += '1';
	cout << s << endl;

	s += "666666";
	cout << s << endl;

	string ss("2333");

	s += ss;
	cout << s << endl;
	return 0;
}

 运行结果:

2.尾插

push_back 函数

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamchineseprson");

	s.push_back('1');
	cout << s << endl;

	s.push_back('2');
	cout << s << endl;

	s.push_back('3');
	cout << s << endl;

	return 0;
}

运行结果:

3.append函数
#include <iostream>
#include <string>

using namespace std;
int main()
{
	string s("iamchineseperson");

	// 追加n个字符
	s.append(1, '1');
	cout << s << endl;

	// 追加一个字符串
	s.append("12345");
	cout << s << endl;

	// 追加一个字符串的前n个
	s.append("12345678", 3);

	cout << s << endl;
	return 0;
}

运行结果:

4.insert 函数

string& insert (size_t pos, const string& str);
//insert函数能够在字符串任意位置插入一个string容器内的字符串

string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
//insert函数能够在字符串任意位置插入一个string对象内的字符串的一段字符串

string& insert (size_t pos, const char* s);
//insert函数能够在字符串一段字符串

string& insert (size_t pos, const char* s, size_t n);
//insert 函数还能够在字符串任意位置插入字符串的前 n 个

string& insert (size_t pos, size_t n, char c);
//insert 函数还能够在字符串任意位置插入n个字符
//插入
int main()
{
	string s1("iamchineseperson");
	string s2("hello");

	//在pos位置插入string
	s1.insert(0, s2);
	cout << s1 << endl;

	//在pos位置插入char*
	s1.insert(0, "hehe");
	cout << s1 << endl;

	// 在最后插入string的一部分
	s1.insert(s1.size(), s2, 0, 2);
	cout << s1 << endl;


	// 在第一个位置插入string
	s1.insert(0, "sadasdxzczasd");
	cout << s1 << endl;

	return 0;
}

至于其他情况这里我就不多展示了。

2.删

//清空
clear()

//尾删
pop_back();

//erase 删除
//删除从pos位置开始删除len个
string& erase (size_t pos = 0, size_t len = npos);
//删除迭代器p位置	
iterator erase (iterator p);
//删除迭代器区间左闭右开
iterator erase (iterator first, iterator last);

1. erase 函数
string& erase (size_t pos = 0, size_t len = npos);

erase 函数能够删除第 n 个位置后面长度为 len 的字符串

如果没有传 len 或是 第 n 个位置后面的字符数小于 len ,则n后面的字符全部删除

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("iamaperson");

	s.erase(3, 2);
	cout << s << endl;

	s.erase(1);
	cout << s << endl;

	return 0;
}

运行结果:

2.尾删

pop_back()

#include <iostream>
#include <string>

int main ()
{
  std::string str ("hello world!");
  str.pop_back();
  std::cout << str << '\n';
  return 0;
}

运行结果:

3.clear()
// string::clear
#include <iostream>
#include <string>

int main ()
{
  char c;
  std::string str;
  std::cout << "Please type some lines of text. Enter a dot (.) to finish:\n";
  do {
    c = std::cin.get();
    str += c;
    if (c=='\n')
    {
       std::cout << str;
       str.clear();
    }
  } while (c!='.');
  return 0;
}

该程序重复用户引入的每一行,直到一行包含一个点 ('.')。每个换行符 ('\n') 都会触发行的重复和当前字符串内容的清除。

这里我就不运行了

3.查

//find从pos位置向后查找  找到返回下标位置,找不到返回npos
//查找字符串str
size_t find (const string& str, size_t pos = 0) const;
//查找字符串s
size_t find (const char* s, size_t pos = 0) const;
//查找字符c
size_t find (char c, size_t pos = 0) const;

//rfind 从pos位置向前找 找到返回下标位置,找不到返回npos
size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;	
size_t rfind (char c, size_t pos = npos) const;
1.find()
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("i am  a studentt");
	string str("student");

	// 查找 str --> 找得到
	int pos = s.find(str, 0);
	cout << "str pos : " << pos << endl;

	// 查找字符串 --> 找得到
	pos = s.find("a", 0);
	cout << "a pos : " << pos << endl;

	// 查找字符串 --> 找不到
	pos = s.find("A", 0);
	cout << "A pos : " << pos << endl;

	// 查找字符 --> 找得到
	pos = s.find('s', 0);
	cout << "s pos : " << pos << endl;

	// 查找字符 --> 找不到
	pos = s.find('I', 0);
	cout << "I pos : " << pos << endl;

	return 0;
}

运行结果:

2.rfind()
//rfind 从pos位置向前找 找到返回下标位置,找不到返回npos
size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;	
size_t rfind (char c, size_t pos = npos) const;
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("i am  a studentt");
	string str("student");

	// 查找 str --> 找得到
	int pos = s.rfind(str);
	cout << "str pos : " << pos << endl;

	// 查找字符串 --> 找得到
	pos = s.rfind("a");
	cout << "a pos : " << pos << endl;

	// 查找字符串 --> 找不到
	pos = s.rfind("a", 0);
	cout << "A pos : " << pos << endl;

	// 查找字符 --> 找得到
	pos = s.rfind('s',8);
	cout << "s pos : " << pos << endl;

	// 查找字符 --> 找不到
	pos = s.rfind('s', 5);
	cout << "I pos : " << pos << endl;

	return 0;
}

4.改

//assign 全部替换
//用字符串str替换原来的内容
string& assign (const string& str);
//用字符串s替换原来的内容
string& assign (const char* s);	
//迭代器first到迭代器last这个区间替换原来的内容 左闭右开
template <class InputIterator>
   string& assign (InputIterator first, InputIterator last);

//replace替换一部分
//将pos到len位置替换成str
string& replace (size_t pos,  size_t len,  const string& str);
//将迭代器i1到i2替换成str
string& replace (iterator i1, iterator i2, const string& str);
 //将pos到len位置替换成s
string& replace (size_t pos,  size_t len,  const char* s);
//将迭代器i1到i2替换成s 左闭右开
string& replace (iterator i1, iterator i2, const char* s);

1.assign()
int main()
{
	string s1("i am  a studentt");
	string s2("student");

	//修改stirng
	s1.assign(s2);
	cout << s1 << endl;
	//修改char *
	s1.assign("he");
	cout << s1 << endl;

	//迭代器
	s1.assign(s2.begin(), s2.end());
	cout << s1 << endl;

	return 0;
}

运行结果:

2.replace()

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1("i am  a student");
	string s2("person");
	//将pos到len位置替换string
	s1.replace(8, 15, s2);
	cout << s1 << endl;

	//将pos到len位置替换char*
	s1.replace(0, 0, "asdsd");
	cout << s1 << endl;
	return 0;
}

运行结果:

2.6 一些小东西的介绍

1. npos

npos的值通常是一个很大的正数,等于-1(当作为无符号数解释时或等于string::size_type的最大可能值。

2.c_str 函数

作用:返回C格式字符串

C++中,printf 是一个C语言函数,它不支持直接打印std::string类型的内容。这是因为 printf 是一个可变参数函数,而 std::string 不是基本数据类型,因此需要转换为C风格字符串才能由 printf 输出。

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s("Hello world");

	printf("%s\n", s);
	printf("%s\n", s.c_str());

	return 0;
}

运行结果:

3.substr()

string substr (size_t pos = 0, size_t len = npos) const;

在字符串中从第pos个位置开始截取len个字符返回

// string::substr
#include <iostream>
#include <string>

int main ()
{
  std::string str="We think in generalities, but we live in details.";
                                           // (quoting Alfred N. Whitehead)

  std::string str2 = str.substr (3,5);     // "think"

  std::size_t pos = str.find("live");      // position of "live" in str

  std::string str3 = str.substr (pos);     // get from "live" to the end

  std::cout << str2 << ' ' << str3 << '\n';

  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/591553.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于HSI模型的水下图像增强算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

MYSQL从入门到精通(二)

1、MYSQL高级概述 【1】架构概述 【2】索引优化 【3】查询截取 【4】mysql锁机制 【5】主从复制 2、MYSQL概述 【1】mysql内核 【2】sql优化工程师 【3】mysql服务器的优化 【4】各种参数常量设定 【5】查询语句优化 【6】主从复制 【7】软硬件升级 【8】容灾百分 【9】sql编…

自动安装环境shell脚本使用和运维基础使用讲解

title: 自动安装环境shell脚本使用和运维基础使用讲解 tags: [shell,linux,运维] categories: [开发记录,系统运维] date: 2024-3-27 14:10:15 description: 准备和说明 确认有网。 依赖程序集&#xff0c;官网只提供32位压缩包&#xff0c;手动编译安装后&#xff0c;在64位机…

springboot整合mybatis配置多数据源(mysql/oracle)

目录 前言导入依赖坐标创建mysql/oracle数据源配置类MySQLDataSourceConfigOracleDataSourceConfig application.yml配置文件配置mysql/oracle数据源编写Mapper接口编写Book实体类编写测试类 前言 springboot整合mybatis配置多数据源&#xff0c;可以都是mysql数据源&#xff…

QT:布局管理器

文章目录 垂直布局使用QVBoxLayout来管理多个控件 水平布局使用QHBoxLayout管理控件 网格布局创建QGridLayout管理四个按钮设置元素的大小比例 表单布局 在之前QT的界面控件中&#xff0c;都是使用绝对定位来完成的&#xff0c;也就是说是用绝对坐标的方式来设置进去的 这样并…

网站高级认证页面模板(自定义安全认证)

网站高级认证页面模板&#xff08;自定义安全认证&#xff09; 仅限于源码测试&#xff0c;不代表真实性 下载地址&#xff1a; https://yuncv.lanzouw.com/i98qC1xm8u4j

ue引擎游戏开发笔记(29)——实现第三人称角色随手柄力度进行移动

1.需求分析 角色可以随手柄力量大小进行走路和跑步&#xff0c;不动时保持角色停顿。 2.操作实现 1.思路&#xff1a;通过动画蓝图和动画混合实现角色移动和输入的联系。 2.建立动画蓝图和混合空间&#xff1a; 3.在混合空间中对角色移动进行编辑&#xff1a; 4.在蓝图中设定变…

Springboot图片上传【本地+oss】

文章目录 1 前端组件页面2 本地上传3 上传到阿里云oss3.1申请开通账号&#xff0c;做好先导准备3.2 开始使用 1 前端组件页面 使用的VueElement组件 在线cdn引入&#xff1a; <script src"https://cdn.bootcdn.net/ajax/libs/vue/2.7.16/vue.js"></script&…

深入教程:在STM32上实现能源管理系统

引言 能源管理系统&#xff08;EMS&#xff09;在提高能源效率、减少能源消耗和支持可持续发展方面起着关键作用。本教程将介绍如何在STM32微控制器上开发一个能源管理系统&#xff0c;这种系统能够监控和控制能源使用&#xff0c;适用于家庭自动化、工业控制系统以及任何需要…

ARP欺骗使局域网内设备断网

一、实验准备 kali系统&#xff1a;可使用虚拟机软件模拟 kali虚拟机镜像链接&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 注意虚拟机网络适配器采用桥接模式 局域网内存在指定断网的设备 二、实验步骤 打开kali系统命令行&#xff1a;ctrlaltt可快…

定点小数_

目录 定点小数表示和运算 定点小数的原码 定点小时加减法运算 定点小数 vs 定点整数 定点小数表示和运算 定点小数的原码 定点小数原反补转换 定点小时加减法运算 定点小数 vs 定点整数 定点小数原码依然是 取值范围等比数列 符号位 定点小数 同样的:

QT5之事件——包含提升控件

事件概述 信号就是事件的一种&#xff0c;事件由用户触发&#xff1b; 鼠标点击窗口&#xff0c;也可以检测到事件&#xff1b;产生事件后&#xff0c;传给事件处理&#xff0c;判断事件类型&#xff0c;后执行事件相应函数&#xff1b; 类似单片机的中断&#xff08;中断向量…

C语言 联合和枚举

目录 1. 联合体1.1 联合体类型的声明1.2 联合体变量的创建1.3 联合体的特点1.4 联合体在内存中的存储1.5 联合体使用举例 2. 枚举类型2.1 枚举类型的声明2.2 枚举变量的创建和初始化2.3 枚举类型的大小2.4 枚举类型的优点 正文开始 上次我们通过《C语言 结构体详解》学习了结构…

基于SpringBoot的饭店外卖平台的设计与实现

项目描述 这是一款基于SpringBoot的饭店外卖平台的系统 模块描述 用户端 登录 首页 商家信息 点餐 菜品列表 下单 订单列表 账号下单列表 个人中心 个人资料 修改信息 评论管理 评论菜品 查看评论 打赏骑手 打赏骑手 管理员 登录 菜品管理 修改 下架 订单列表 下单记录 菜品管理…

领域驱动设计(DDD)笔记(一)基本概念

文章链接 领域驱动设计&#xff08;DDD&#xff09;笔记&#xff08;一&#xff09;基本概念-CSDN博客领域驱动设计&#xff08;DDD&#xff09;笔记&#xff08;二&#xff09;代码组织原则-CSDN博客领域驱动设计&#xff08;DDD&#xff09;笔记&#xff08;三&#xff09;后…

C#知识|事件集中响应,多个按钮关联同一事件(实例练习)

哈喽&#xff0c;你好&#xff0c;我是雷工&#xff01; 本节学习窗体Controls集合、控件事件的统一关联及如何优化重复代码。 01 事件集中响应 原理&#xff1a;就是相同的控件&#xff0c;可以关联同一个事件响应方法。 02 示例演示 2.1、示例功能 该示例实现窗体中选择…

光伏光热热泵系统(PVT)介绍

伏光热PVT热泵是一种主动利用太阳辐射能的有效方式&#xff0c;其不仅能够进行光伏发电&#xff0c;还能够利用少量的电能提高热能的品位。太阳能PVT热泵除具有发电和制热的功能外&#xff0c;还可以制冷&#xff0c;其产生的冷能可用于夏季建筑室内温度的调节。 与此同时&…

STM32单片机wifi云平台+温度+烟雾+火焰+短信+蜂鸣器 源程序原理图

目录 1. 整体设计 2. 液晶显示 3. Ds18b20温度传感器 4. Mq2烟雾传感器 5. 火焰传感器传感器 6. 蜂鸣器驱动控制 7. 按键 8. Gsm短信模块 9. Esp8266wifi模块 10、源代码 11、资料内容 资料下载地址&#xff1a;STM32单片机wi…

Adobe-Premiere-CEP 扩展 入门-视频剪辑-去气口插件-Silence Remover

短视频&#xff0c;这两年比较火&#xff0c;不要再问为什么用Premiere&#xff0c;非常难用&#xff0c;为什么不用某影&#xff0c;某些国内软件非常接地气简单&#xff0c;又例如某音资深的视频短编辑就很好用了。。。 Premiere二次开发调试难&#xff0c;不如自己搞个cons…

展开说说:Android Fragment完全解析-卷三

本文章分析了Fragment的管理器FragmentManager、事务FragmentTransaction 、以及完整的声明周期和动态加载Fragment的原理解析。 1、Fragment管理器 FragmentManager 类负责在应用的 fragment 上执行一些操作&#xff0c;如添加、移除或替换操作&#xff0c;以及将操作添加到…