string类部分(C++)

目录

 

1. string类

1.1 auto和范围for

auto关键词:

 范围for:

1.2 string类的常用接口说明

a)string类对象的常见构造

b) string类对象的容量操作

 size与length:

 capacity:

empty:

clear:

 reserve:

1.reserve(n)中n<>

 2.reserve(n)中n>size并且n<>

 3.reserve(n)中n>capacity时

 resize:

1.resize(n),n:<>

 2.resize(n),n>size并且n:<>

3.resize(n),n>capacity: 

 1.3 string类对象的访问及遍历操作

operator[]:

 begin+end:

 rbegin+rend:

1.4. string类对象的修改操作

push_back:

 append:

string& append(const string&str)和string& append(const char*s):

string& append(const string&str,size_t subpos,size_t sublen) 

operator+=:

 c_str:

 find+nops:

size_t find(char c, size_t pos=0) const:

 rfind:

size_t rfind(char c, size_t pos=0) const:

 substr:

 1.5 string类非成员函数

operator>>和operator<<:

 getline:


 

1. string类

在使用string类时,必须包含#include头文件以及using namespace std;

1.1 auto和范围for

auto关键词:

a)在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

b)用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

c)当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

d)auto不能作为函数的参数,可以做返回值,但是建议谨慎使用

e)auto不能直接用来声明数组

举例b):

int x = 10;

auto y = &x;
auto* z = &x;

auto& m = x;

cout << typeid(x).name() << endl;
cout << typeid(y).name() << endl;
cout << typeid(z).name() << endl;
cout << typeid(m).name() << endl;

结果:47370c223a394b99ad8f6e67e6e4d74f.png

这里auto y=&x;和auto* z=&x;是达到相同的效果,但是要注意如果是auto*就右边必须是取地址否则就会报错,不能写成auto* y=x,但第二种auto y=&x,就会自动将其识别为int*类型。

举例c):

auto aa = 1, bb = 2;
// 编译报错:error C3538: 在声明符列表中,“auto”必须始终推导为同一类型
auto cc = 3, dd = 4.0;

第二种定义就会报错,当cc=3事,编译器就会认为这是int类型,但后面dd不匹配,就会报错。

 举例d):

// 不能做参数
//error C3533: 参数不能为包含“auto”的类型
void func2(auto a)
{
}

当函数中的形参用auto类型就会直接报错。

举例e):

// 编译报错:error C3318: “auto []”: 数组不能具有其中包含“auto”的元素类型
auto array[] = { 4, 5, 6 };

这里数组前面定义为auto类型,也会直接报错。

 范围for:

a)对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此 C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。

b)范围for可以作用到数组和容器对象上进行遍历。

c)范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。

 举例:

int main()
{
	int array[] = { 1, 2, 3, 4, 5 };
	// C++98的遍历
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
	{
		array[i] *= 2;
	}
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
	{
		cout << array[i] <<" ";
	}
    cout << endl;
	// C++11的遍历
	for (auto& e : array)
		e *= 2;
	for (auto e : array)
		cout << e << " ";
    cout<<endl;
	return 0;
}

结果:c90bf175f78e4a288b4e1e28fa0a0a7e.png

1.2 string类的常用接口说明

a)string类对象的常见构造

74715281ea2a4531bc676b725a54b2bf.png

 举例:

int main()
{
	string s1;                // 构造空的string类对象s1
	string s2("hello world");   // 用C格式字符串构造string类对象s2
	string s3(s2);            // 拷贝构造s3
	string s4(4, 'c');			//构造n个c
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
}

结果:808ee4407a0a490897805ce3824e8da0.png

b) string类对象的容量操作

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

 

 

 

 

 

 

 

 

 

 size与length:

举例:

int main()
{
	string s1("hello world");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
}

结果:c922bb8f7bea4c229018045612bbbd50.png

注意:size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接 口保持一致,一般情况下基本都是用size()。

 capacity:

举例:

void test1()
{
	string s1("hello world");
	cout << s1.capacity() << endl;
}

结果:b90410c5d7b64e249b9efa77587436f4.png

这里还要看一下一次开多大的空间,如何开空间的(通过下面代码观察一下每次开多大)

int mian()
{
	string s;
	size_t old = s.capacity();
	cout << "capacity changed: " << old << '\n';
	cout << "making s grow:\n";
	for (int i = 0; i < 1000; ++i)
	{
		//s.push_back('c');
		s += 'c';
		if (old != s.capacity())
		{
			old = s.capacity();
			cout << "capacity changed: " << old << '\n';
		}
	}
}

结果:e7e258dee39846b2b644447880422bcc.png

在vs2022编译器下,第一次开辟十六个空间(这是15是表示有效存储空间,因为这里还要放“\0”),第一次为2倍,后面都是前面的1.5倍。

还要注意调试时,观察当字符小于16,当字符大于16。

void test4()
{
	string s1("11111");
	string s2("2222222222222222222222222222");
}

c9512a7497024b1385c3da78d6953a3a.png

e12783ddc86f4602bde44e0cf6aa7ca4.png

这里发现在vs2022下成员变量中有一个_Buf,就是说当字符数小于16时,就直接存放在_Buf中,避免去频繁调用开辟空间,当大于16时,再在_Ptr调用开辟空间,将字符存放在_Ptr中。

empty:

举例:

int main()
{
	string s1("hello world");
	string s2;
	cout << s1.empty() << endl;
	cout << s2.empty() << endl;
}

结果:472061f71842470e99bc5c8c619b86ec.png

为空时,返回1,否则,返回0。

clear:

举例:

void test2()
{
	string s1("hello world");
	s1.clear();
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
}

结果:247c98b065fb4d5e883c5b2e614e2a4f.png

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

 reserve:

举例:reserve分为三种情况:

这里先补充一个函数shrink_to_fit()缩容的作用

1.reserve(n)中n<size

void test5()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.reserve(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:cf4d3be86a734f7dbb8ac865f78a7695.png

可以看当n<size时,在vs2022编译器下面reserve并没有缩容减小空间而是保持不变。

 2.reserve(n)中n>size并且n<capacity


void test5()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.reserve(13);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:6db696ca5d404c568fda502d2fc6fbaa.png

可以看到这里很前面的结果一样,在vs2022下只要n是小于capacity时,就不进行缩容,不操作,保持原来的不变。

 3.reserve(n)中n>capacity时

void test5()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.reserve(20);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:ecc9a74bf67441e4b96850c0fa767b03.png

这里发现当n>capacity时,在vs2022编译器下,会开辟空间,遵循上面的开辟规则,当所需开辟的空间不足上面的那一个档位时,(例如:我要开辟20个,但根据上面的规则,会直接开辟31个,如果要开辟32,这个31不够,就会直接开辟47个)也会直接开辟那个档位所需的空间。

这里补充一个函数shrink_to_fit:

void test5()
{
	string s("1111111111");
	s.reserve(1000);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.shrink_to_fit();
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:711696cbf3824e5599da177b6c5c630a.png

这个函数是用来缩容的,但是注意,这个函数是异地缩容,即是重新开辟一块缩容大小之后的空间。(不建议使用)

 resize:

这里同reserve一样分为三种情况:

1.resize(n),n<size:

void test6()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.resize(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:e9ec22c56d894287a9d588475d20e0b9.png

 590910c9e3a644a696cca63979074f6f.pngbbb7903cd2c04debb4b74070fac4845e.png

可以看到当n<size时,会直接多余的(大于n的)删除数据,并将size大小改为n。

 2.resize(n),n>size并且n<capacity:

void test6()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.resize(13);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:87365e4ed1454fd8b54c8e54d6209c2f.png

06ddaa4dfc054737911a8731384fa2fc.png020706629a664834bbae4abedfa12821.png

可以观察到,这里会将不到n部分的size放置为0,之前原有的数据不变,并将size大小改为n。

3.resize(n),n>capacity: 

void test6()
{
	string s("1111111111");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.resize(20);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

结果:4273236043cc4df0afcf02475d2788cb.png

30b4ab1cbb1f4b80806ac4e84f69ff1a.pngfc7357e299e04615895f8b0273f94bb0.png

 这里可以观察到,当n>capacity时,就会开辟新的空间,然后和第二种情况一样,将不到n的部分,补为'\0',之前的部分不变。

总结:1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

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

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

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参 数小于string的底层空间总大小时,reserver不会改变容量大小。

 1.3 string类对象的访问及遍历操作

函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin+endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位 置的迭代器
rbegin+rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位 置的迭代器
范围forC++11支持更简洁的范围for的新遍历方式

operator[]:

void test7()
{
	string s("abcdef");
	for(int i=0;i<s.size();i++)
		cout << s[i] << " ";
}

结果:e5fa34b218784786a7f3c938b4439efc.png

这里和C语言的下标访问是一样的,只是这里进行了函数重载,将其封装了一下。

 begin+end:

void test7()
{
    string s("abcdef");
	string::iterator i = s.begin();
	while (i != s.end())
	{
		cout << *i << " ";
		i++;
	}
}

结果:fa7aaf9f6f6148ccb26acf03f35a8d85.png

这里的迭代器中的begin(),相当于是指针的用法,但这里不是指针。

 rbegin+rend:

string s("abcdef");
string::reverse_iterator i1 = s.rbegin();
while (i1 != s.rend())
{
	cout << *i1 << " ";
	i1++;
}

结果:b7631d78031d4d36a2164602d8353586.png

这里就是从最后一个字符开始遍历直到第一个字符,和begin(),end()逻辑是一样的。

1.4. string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=在字符串后追加字符串str
c_str返回C格式字符串
find+npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的 位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的 位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

push_back:

void test8()
{
	string s("abcdef");
	for (int i = 0; i < 5; i++)
	{
		s.push_back('a');
	}
	cout << s << endl;
}

结果:31cd74ef82204feb9a42cb411ff0d521.png

直接在字符串末尾加字符c 。

 append:

8d2698ae2b5c4290b38f58e46c9cf549.png

这里append在类中有六个接口,这里讲几个较常用的:

string& append(const string&str)和string& append(const char*s):

void test8()
{
	string s1("abcdef");
	string s2("hijklm");
	s1.append(s2);
	s2.append("abcdef");
	cout << s1 << endl;
	cout << s2 << endl;
}

结果:01f1d5324cc847529e2eaee6dcf451aa.png

这里传参可以是一个string类,也可以是常量字符串,都是直接在后面插入。

string& append(const string&str,size_t subpos,size_t sublen) 

void test8()
{
	string s1("abcdef");
	string s2("hijklm");
	s1.append(s2, 2, 3);
	cout << s1 << endl;
}

结果:a070c94392684aa4bca659921939b5c3.png

这里第一个参数是要插入的string类,第二个参数是从s2下标第几个位置开始插入,第三个参数是要插入的个数。

operator+=:

cf5e9267646f4e7a81c844acbb27cae9.png

 

void test9()
{
	string s1("hello ");
	string s2("world");
	const char* s = "hhhhh";
	s1 += s2;
	cout << s1 << endl;
	s2 += s;
	cout << s2 << endl;
	s1 += 'a';
	cout << s1 << endl;
}

结果:74848425113f4545a4365f0a4c6d5bc9.png

这里和append非常相似,都是直接在后面追加字符,字符串,和string类,这种增加的方式用的较多,且代码可读性较高。

 c_str:

void test9()
{
	string s1("hello ");
	cout << s1.c_str() << endl;
}

结果:34beea632ba6475ca63abbeca752e734.png

这里就是返回类里面的字符串,这里因为是c语言格式,所以字符最后有“\0”。

 find+nops:

13f5736696ef42f18477ef36fbccdc37.png

这里讲常用的函数接口:

size_t find(char c, size_t pos=0) const:

void test10()
{
	string s("hello world");
	size_t pos = s.find(' ',0);
	cout << pos << endl;
}

结果:7b2667634a014a219257643823085dcb.png

这里是从pos位置,寻找第一次出现字符c的位置,并返回该位置的下标。

 rfind:

5c697cb709b94354b25275d8d45866f4.png

这里讲常用的函数接口:

size_t rfind(char c, size_t pos=0) const:

void test10()
{
	string s("hello world hello");
	size_t pos = s.rfind(' ');
	cout << pos << endl;
}

结果:b19f996c632f418a83adb117c6425e0f.png

这里是从pos位置向前寻找,默认pos参数是npos,相当于是从最后开始向前找字符c,并返回该位置下标。

 substr:

void test10()
{
	string s1("hello ");
	string s2=s1.substr(1, 3);
	cout << s2 << endl;
}

结果:9ddd012b1fd34dd388d30155c162b959.png

这里函数是将s1从pos=1,位置开始,拷贝3个字符到s2上。

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

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

 1.5 string类非成员函数

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>>输入运算符重载
operator<<输出运算符重载
getline获取一行字符串
relational_operator大小比较

这里operator+,就是和operator+=差不多,都在后面增加字符,不建议用是因为这是传值返回,深拷贝效率太低了。

operator>>和operator<<:

这里和小编之前实现的Date日期类的用法一样,可以去之前的文章“赋值运算符重载”翻阅。 

 getline:

bc1dffd2e0bb462aa7f53989eb1971ab.png

void test11()
{
	string s;
	getline(cin, s);
	cout << s << endl;
}

结果:5fff418e72bf485cb8f1172ef4bc84c2.png

这里getline函数是流提取,但这里是读取一行的字符直到换行符,不会像cin或scanf到空格就停止了。

void test11()
{
	string s;
	getline(cin, s,'&');
	cout << s << endl;
}

结果:75aa5200f85b499c976e8e48a17786af.png

这里可以再传一个参数,表示当遇到字符c才停止,甚至换行都不行。

 

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

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

相关文章

实现一个可配置的TCP设备模拟器,支持交互和解析配置

前言 诸位在做IOT开发的时候是否有遇到一个问题&#xff0c;那就是模拟一个设备来联调测试&#xff0c;虽然说现在的物联网通信主要是用mqtt通信&#xff0c;但还是有很多设备使用TCP这种协议交互&#xff0c;例如充电桩&#xff0c;还有一些工业设备&#xff0c;TCP这类报文交…

Redis主从架构

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的键值对存储系统&#xff0c;广泛应用于缓存、消息队列、实时分析等场景。为了提高系统的可用性、可靠性和读写性能&#xff0c;Redis提供了主从复制&#xff08;Master-Slave Replication&#xf…

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中&#xff0c;校运会不仅是…

软件团队的共担责任

问责制被认为是个人与其社会系统之间的纽带&#xff0c;它创造了一种将个人与其行为和绩效联系起来的身份关系。在入门系列的第一篇文章《超越工具和流程&#xff1a;成功软件开发团队的策略》中&#xff0c;我们介绍了问责制的概念&#xff0c;并提出了以下定义&#xff1a; …

学习日记_20241126_聚类方法(谱聚类Spectral Clustering)

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

如何使用Jest测试你的React组件

在本文中&#xff0c;我们将了解如何使用Jest&#xff08;Facebook 维护的一个测试框架&#xff09;来测试我们的React组件。我们将首先了解如何在纯 JavaScript 函数上使用 Jest&#xff0c;然后再了解它提供的一些开箱即用的功能&#xff0c;这些功能专门用于使测试 React 应…

硬菜!高精度!BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断

硬菜&#xff01;高精度&#xff01;BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断 目录 硬菜&#xff01;高精度&#xff01;BO-Transformer贝叶斯优化编码器多特征分类预测/故障诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transform…

仿真学习 | Abaqus版本差异详解:哪版更适合你的仿真作业?

​ 引言 在上一篇文章《仿真学习 | Fluent版本迭代一览及选择指南》中&#xff0c;我们深入探讨了Fluent的不同版本以及如何根据自身需求选择最合适的版本。今天&#xff0c;我们将把视线聚焦于Abaqus——另一款在工程仿真领域中备受推崇的软件。 在有限元分析领域&#xff0c;…

NLP论文速读(剑桥大学出品)|分解和利用专家模型中的偏好进行改进视觉模型的可信度

论文速读|Decompose and Leverage Preferences from Expert Models for Improving Trustworthiness of MLLMs 论文信息&#xff1a; 简介&#xff1a; 本文探讨的背景是多模态大型语言模型&#xff08;MLLMs&#xff09;&#xff0c;这类模型通过结合视觉特征和文本空间来增强语…

IntelliJ IDEA 中,自动导包功能

在 IntelliJ IDEA 中&#xff0c;自动导包功能可以极大地提高开发效率&#xff0c;减少手动导入包所带来的繁琐和错误。以下是如何在 IntelliJ IDEA 中设置和使用自动导包功能的详细步骤&#xff1a; 一、设置自动导包 打开 IntelliJ IDEA&#xff1a; 启动 IntelliJ IDEA 并打…

红外小目标检测

目录 背景概述算法原理演示效果核心逻辑 使用方式基础镜像配置环境直接运行 参考文献 文章声明&#xff0c;非广告&#xff0c;仅个人体验。 背景 红外图像在许多领域中都有所应用。例如军事领域中&#xff0c;经常需要通过红外成像设备对远距离的目标进行侦察和监视&#xff…

hive的存储格式

1&#xff09; 四种存储格式 hive的存储格式分为两大类&#xff1a;一类纯文本文件&#xff0c;一类是二进制文件存储。 Hive支持的存储数据的格式主要有&#xff1a;TEXTFILE、SEQUENCEFILE、ORC、PARQUET 第一类&#xff1a;纯文本文件存储 textfile: 纯文本文件存储格式…

ReentrantLock(可重入锁) Semaphore(信号量) CountDownLatch

目录 ReentrantLock(可重入锁) &Semaphore(信号量)&CountDownLatchReentrantLock(可重入锁)既然有了synchronized&#xff0c;为啥还要有ReentrantLock?Semaphore(信号量)如何确保线程安全呢&#xff1f;CountDownLatch ReentrantLock(可重入锁) &Semaphore(信号量…

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…

STM32C011开发(2)----nBOOT_SEL设置

STM32C011开发----2.nBOOT_SEL设置 概述硬件准备视频教学样品申请源码下载参考程序自举模式BOOT0设置配置 nBOOT_SEL生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32CubeProgrammer (STM32CubeProg) 是一款用于编程STM32产品的全功能多操作系统软件工…

基于 AI 的软件工程: 超级程序员

徐昊 《AI时代的软件工程》-极客时间课程学习总结 帮助你更好地利用 LLM 提高效率,还可以站在一个更全面的立场上,讨论如何将 LLM 引入团队或是组织。 核心观点: AI 辅助业务建模:通过将模型转化为 Mermaid 格式,将我们的模型表达为大语言模型能够理解的形式。通过添加注…

【消息序列】详解(7):剖析回环模式--设备测试的核心利器

目录 一、概述 1.1. 本地回环模式 1.2. 远程环回模式 二、本地回环模式&#xff08;Local Loopback mode&#xff09; 2.1. 步骤 1&#xff1a;主机进入本地环回模式 2.2. 本地回环测试 2.2.1. 步骤 2a&#xff1a;主机发送HCI数据包并接收环回数据 2.2.2. 步骤 2b&…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

计算机网络 第4章 网络层

计算机网络 &#xff08;第八版&#xff09;谢希仁 第 4 章 网络层4.2.2 IP地址**无分类编址CIDR**IP地址的特点 4.2.3 IP地址与MAC地址4.2.4 ARP 地址解析协议4.2.5 IP数据报的格式题目2&#xff1a;IP数据报分片与重组题目&#xff1a;计算IP数据报的首部校验和(不正确未改) …

【Git】常用命令汇总

目录 一.安装及配置 1.在 Windows 上安装 2.用户信息 3.差异分析工具 二.基础 1.创建仓库 2.提交与修改 三.分支管理 1.创建分支 2.合并分支 四.远程操作 1.管理 Git 仓库中的远程仓库 2.数据的获取与推送 五.标签 1.创建轻量标签和附注标签 2.查看标签和标签信…