C++——string的了解和使用

news2024/9/21 22:31:39

目录

引言

为什么要学习string

1.C语言中的字符串

2.C++中的字符串

auto和范围for

1.auto

1.1 auto的介绍

1.2 注意事项

2.范围for

标准库中的string类

1.string类的迭代器

1.1 begin()与end()函数

1.2 rbegin()与rend()函数

2.string类的初始化和销毁

3.string类的容量操作

3.1 有效长度和容量大小

(1)使用示例

(2)扩容机制

3.2 有效长度和扩容操作

(1)reserve函数

(2)resize函数

(3)clear函数

4.string类的访问操作

4.1 operator[]函数

4.2 at函数

4.3 front 和 back 函数

5.string类的修改操作

5.1 字符串增加操作

5.2 字符串替换操作

5.3 字符串删除操作

5.4 字符串交换操作

5.5 字符串其他操作

结束语


引言

为了简化字符串的处理,C++标准库引入了string类。string类是一个模板类,专门用于表示和操作字符串。今天我们来学习一下string。

为什么要学习string

1.C语言中的字符串

C语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 

2.C++中的字符串

为了简化字符串的处理,C++标准库引入了string类。string类是一个模板类,专门用于表示和操作字符串。它不仅封装了字符串的底层细节,如内存分配和释放,还提供了一套丰富而易于使用的成员函数,用于执行各种字符串操作,如拼接、比较、查找、替换、插入和删除等。

下面是一个string的简单使用:

int main()
{
	string s1;
	string s2("hello world");
	string s3(s2);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;

	string s4(s2, 6, 15);
	cout << s4 << endl;

	string s5(s2, 6);
	cout << s5 << endl;

	string s6("hello world", 5);
	cout << s6 << endl;

	string s7(10, 'x');
	cout << s7 << endl;

	return 0;
}

输出结果为:

下面我们来详细学习一下。

auto和范围for

在学习string类之前,我们先来学习一下auto和范围for,方便我们后面的学习。

1.auto

1.1 auto的介绍

auto 关键字用于自动类型推导。编译器会自动根据初始化表达式来推断变量的类型。这避免了在声明变量时显式指定类型,特别是当类型名称很长或复杂时,auto可以使代码更加简洁。

int main()
{
	int i = 0, & ri = i;

	auto a = i;		//a为int型变量
	auto a1 = ri;	//a1为int型变量

	auto p = &i;	// &i 是一个普通int指针,p是一个整型指针int *
	auto p1 = &ri;	//同上

	return 0;
}
1.2 注意事项

(1)使用 auto 声明的变量必须有初始化表达式,否则编译器无法推导其类型

因此,不能这样子:

auto x;

(2)对于模板实例化、复杂表达式等,auto 能够推导出相应的复杂类型

std::vector<int> vec = {1, 2, 3};  
auto v = vec; // v 的类型是 std::vector<int>  
auto result = Fun(x, y); // result 的类型由函数返回类型决定

(3)auto也有一些缺陷,例如它降低了代码的可读性,导致我们无法一眼看出变量的类型(像上面的代码,我们不能直观的看出 v 的类型)。

(4)用 auto 声明指针类型时,用 auto 和 auto* 没有任何区别,只是 auto* 必须是指针。但是用 auto 声明引用类型时,必须加 & 。

int x = 1;
auto a = &x;
auto* b = &x;
auto& c = x;

2.范围for

范围for(也称为基于范围的for循环)是C++11引入的一种新的循环语法,用于简化对容器(如vector、list、map等)、数组或初始化列表中的元素进行遍历的操作。这种循环语法使得代码更加简洁、清晰,提高了代码的可读性和可维护性。

范围for循环的基本语法如下:

for (元素类型 变量名 : 容器或数组名) 
{  
    // 循环体  
}

来看个简单的例子:

int main()
{
	int arr[] = { 1,2,3,4,5 };
	for (auto i : arr)
	{
		cout << i << endl;
	}
	return 0;
}

输出结果为:

由于 i 是临时变量,不能直接修改数组元素的值,我们需要使用引用 & 。

int main()  
{  
    int arr[] = { 1, 2, 3, 4, 5 };  
    for (auto& i : arr) // 注意这里使用了引用&  
    {  
        i *= 2; // 修改数组元素的值  
        cout << i << endl;  
    }  
    return 0;  
}

输出结果为:

标准库中的string类

我们可以使用以下文档来辅助我们学习string:

string类的接口详细介绍

1.string类的迭代器

迭代器(Iterator)在C++中是一种抽象化的概念,它提供了一种统一的方法来遍历容器中的元素,而无需了解容器内部的具体实现细节。

迭代器在行为上类似于指针,但它不仅仅局限于原始指针的功能。迭代器封装了对容器元素的访问,并且根据容器的不同,迭代器可以有不同的实现。然而,从用户的角度来看,迭代器提供了一种统一的接口来遍历容器,这使得代码更加通用和可移植。

当我们使用迭代器时,确实可以将其当作指针来使用,但需要注意的是,迭代器并不是指针的替代品,而是对容器遍历操作的一种抽象。

在 string 类中,我们就可以通过迭代器来访问其具体元素,并且也为我们提供了相应的调用函数。

1.1 begin()与end()函数

迭代器提供了 begin() 和 end() 成员函数,用于获取遍历的起始位置和结束位置。

begin()与end()函数的使用方法具体如下:

begin():

函数声明:

对于非const的std::string对象,iterator begin(); 返回指向第一个字符的iterator。

对于const的std::string对象,const_iterator begin() const; 返回指向第一个字符的const_iterator。

作用:返回指向字符串第一个字符的迭代器。

返回值:

对于非const对象,返回iterator,允许通过迭代器修改字符串中的字符。

对于const对象,返回const_iterator,仅允许通过迭代器读取字符串中的字符,不允许修改。

end() :

函数声明(对于std::string):

iterator end(); 返回指向字符串末尾(即最后一个字符之后的位置)的iterator。

const_iterator end() const; 对于const对象,返回指向字符串末尾的const_iterator。

作用:返回指向字符串末尾(即最后一个字符之后的位置)的迭代器。这个迭代器通常用作遍历循环的结束条件。

我们来尝试使用一下这俩玩意,代码如下:

int main()
{
	string s1("hello world");
	cout << s1 << endl;
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	return 0;
}

输出结果为:

int main()
{
	const string s2("hello world");
	cout << s2 << endl;
	// const迭代器,用于遍历const字符串,不能改变字符串中的值
	string::const_iterator it = s2.begin();
	while (it != s2.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	return 0;
}

输出结果为:

1.2 rbegin()与rend()函数

rbegin:

函数声明(对于 std::string 和其他支持反向迭代器的容器): 

reverse_iterator rbegin();    

const_reverse_iterator rbegin() const;

作用

返回指向容器(如 std::string)中最后一个元素(即反向遍历的起始位置)的反向迭代器。这使得可以反向遍历容器中的元素。

返回值

对于非 const 容器,返回 reverse_iterator。对于 const 容器,返回const_reverse_iterator。

rend:

函数声明(对于 std::string 和其他支持反向迭代器的容器):

reverse_iterator rend();

const_reverse_iterator rend() const;

作用:

返回指向容器(如 std::string)中第一个元素前面一个位置的反向迭代器。这实际上是反向遍历的结束位置,它不指向任何有效元素,而是作为反向遍历的结束标志。

返回值

对于非 const 容器,返回 reverse_iterator。 对于 const 容器,返回 const_reverse_iterator。

来简单的使用一下:

int main()
{
	string s1("hello world");
	cout << s1 << endl;
	string::reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
	return 0;
}

输出结果为:

int main()
{
	const string s2("hello world");
	cout << s2 << endl;
	string::const_reverse_iterator rit = s2.rbegin();
	while (rit != s2.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
	return 0;
}

输出结果为:

2.string类的初始化和销毁

由于 string 是一个类,因此我们在初始化时肯定会调用其构造函数初始化。

(1)默认构造函数:创建一个空的字符串对象。

(2)拷贝构造函数:创建一个新的字符串对象,它是另一个字符串对象的副本。这允许通过现有的字符串来初始化新字符串。

(3)子字符串构造函数:创建一个新的字符串对象,它是另一个字符串对象从pos位置开始、长度为len的子串。如果len是npos(默认情况),则子串从pos开始直到原字符串的末尾。

(4)从C字符串构造函数:使用C风格的字符串(以空字符'\0'结尾的字符数组)来初始化字符串对象。

(5)从C字符串的前n个字符构造函数:使用C风格的字符串的前n个字符来初始化字符串对象。

(6)填充构造函数:创建一个新的字符串对象,其中包含n个重复的字符c。

(7)范围构造函数:这是一个模板构造函数,允许使用任何输入迭代器对(如指针、std::vector的迭代器等)来初始化字符串。它复制从first到last(不包括last)范围内的所有元素到新的字符串对象中。

(1)字符串赋值:这个重载版本允许将一个 std::string 对象的内容赋值给另一个 std::string 对象。这是通过复制 str 的内容到当前对象来实现的。注意,这里使用了引用传递(const string&),这有助于避免不必要的复制,提高效率。

(2)C风格字符串赋值:这个重载版本允许将一个C风格字符串(即以空字符('\0')结尾的字符数组)赋值给 std::string 对象。std::string 会复制 s 指向的C风格字符串的内容(不包括结尾的空字符),并存储在自己的内部表示中。

(3)单个字符赋值:这个重载版本允许你将一个单独的字符赋值给 std::string 对象。这通常会导致 std::string 对象的内容被替换为仅包含该字符的一个新字符串。

下面是代码演示:

int main()
{
	// (1)默认构造函数。
	string s1;
	s1 = "hello world!";
	//(2)拷贝构造函数
	string s2(s1);
	//(3)子字符串构造函数
	string s3(s2, 1, 7);
	//(4)从C字符串构造函数
	string s4("hello world!");
	//(5)从C字符串的前n个字符构造函数
	string s5("hello world!", 5);
	//(6)填充构造函数
	string s6(7, 'a');
	//(7)范围构造函数
	string s7(s1.begin(), s1.end());
	// 赋值运算符重载初始化
	string s8 = "hello world!";
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	cout << s7 << endl;
	cout << s8 << endl;
	return 0;
}

输出结果为:

在C++中,std::string 是一个类模板的实例化,代表了一个可变的字符序列。由于它是一个类,当 std::string 对象的生命周期结束时(即离开其作用域),编译器会自动调用该对象的析构函数来清理其分配的资源。

3.string类的容量操作

在C++中,std::string 类提供了多种与容量(capacity)相关的操作,这些操作允许你查看或修改字符串的内部存储空间的大小。

以下是比较常见的容量操作:

函数名称功能
size返回字符串的有效长度
length返回字符串的有效长度
capacity返回字符串的容量大小
max size返回字符串的最大长度
clear清空字符串
empty检查是否为空串,是则返回true,否则返回false
reserve请求改变字符串的容量
resize重新设置有效字符的数量,超过原来有效长度则用c字符填充
3.1 有效长度和容量大小
(1)使用示例

std::string 的容量(capacity)并不总是等于其当前长度(size)。容量是字符串为了存储更多字符而预先分配的内存量,而长度是当前存储在字符串中的字符数。

我们通过代码来验证一下:

int main()
{
	string s("hello world");
	cout << s.size() << endl;		//有效长度
	cout << s.length() << endl;		//有效长度
	cout << s.capacity() << endl;	//容量大小
	cout << s.max_size() << endl;	//最大大小
	return 0;
}

输出结果为:

其中有效长度 size 以及容量大小 capacity 不包括\0。而 max_size 返回字符串最大容量,不同平台下大小可能不一样。

还有一个判空函数empty(),下面是一个简单的使用示例:

int main()
{
	string s1("");
	string s2("hello world");
	if (s1.empty())
	{
		cout << "s1为空串" << endl;
	}
	else
	{
		cout << "s1不为空串" << endl;
	}
	if (s2.empty())
	{
		cout << "s2为空串" << endl;
	}
	else
	{
		cout << "s2不为空串" << endl;
	}
	return 0;
}

输出结果为:

(2)扩容机制

我们接下来研究一下string的扩容机制:

来看看这段代码:

int main()
{
	string s;
	size_t sz = s.capacity();
	cout << "making s grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
	return 0;
}

输出结果为:

我们可以看到,在vs2022中,string大致以一点五倍进行扩容处理。我们来看看在g++编译器的运行结果:

我们可以看到,在这里是二倍扩容处理。

3.2 有效长度和扩容操作

我们先来学习两个可以改变容量的函数 reserve,resize。

(1)reserve函数

reserve函数用于请求改变字符串的容量(capacity),即为其内部存储空间分配至少能容纳n个字符的空间。

来测试一下:

int main()
{
	string s1;
	s1.reserve(50);
	cout << s1.capacity() << endl;
	return 0;
}

输出结果为:

系统开辟的空间往往是大于程序员设定的空间的,且遵循对齐原则。

(2)resize函数

resize函数用于改变字符串的大小(size),即改变其中包含的字符数。

如果 n 小于当前字符串的长度,则 resize 函数会将字符串缩短到前 n 个字符,并删除超出第 n 个字符之后的所有字符。

如果 n 大于当前字符串的长度,则 resize 函数会扩展字符串,以便它能够包含 n 个字符。这通常涉及到在字符串的末尾添加新的字符。

如果调用时提供了第二个参数 c,则这些新添加的字符将被初始化为 c 的副本。

如果没有提供第二个参数 c,则新添加的字符是值初始化的。

n<size:

测试代码:

void test1()
{
	string s1 = "hello world";
	cout << "字符个数:" << s1.size() << endl;
	cout << "空间大小:" << s1.capacity() << endl << endl;

	s1.resize(10);
	cout << "修改后字符个数:" << s1.size() << endl;
	cout << "修改后空间大小:" << s1.capacity() << endl;
}

输出结果:

size < n < capacity:

测试代码:

void test2()
{
	string s1 = "hello world";
	cout << "字符个数:" << s1.size() << endl;
	cout << "空间大小:" << s1.capacity() << endl << endl;

	s1.resize(12);
	cout << "修改后字符个数:" << s1.size() << endl;
	cout << "修改后空间大小:" << s1.capacity() << endl;
}

输出结果为:

n>capacity:

测试代码:

void test3()
{
	string s1 = "hello world";
	cout << "字符个数:" << s1.size() << endl;
	cout << "空间大小:" << s1.capacity() << endl << endl;

	s1.resize(20);
	cout << "修改后字符个数:" << s1.size() << endl;
	cout << "修改后空间大小:" << s1.capacity() << endl;
}

输出结果:

(3)clear函数

string 类提供的 clear 函数用于移除字符串中的所有字符,使其变为空字符串。

下面是个简单的测试:

int main()
{
    string str = "Hello, World!";

    // 检查字符串是否为空  
    if (str.empty())
    {
        cout << "串为空" << endl;
    }
    else
    {
        cout << "串不为空" << endl;
    }

    // 清除字符串  
    str.clear();

    // 检查字符串是否为空  
    if (str.empty()) 
    {
        cout << "串为空" << endl;
    }
    else
    {
        cout << "串不为空" << endl;
    }

    // 输出清空后的字符串  
    cout << "清空后的字符串: " << str << endl;

	return 0;
}

输出结果为:

4.string类的访问操作

string类的访问操作通常有如下几种:

函数名称功能
operator[]返回指定位置的字符,越界则报错
at返回指定位置的字符,越界则抛异常
back返回字符串最后一个字符(不是"0”)
front返回字符串第一个字符
4.1 operator[]函数

string类的operator[]函数是一个重载的下标操作符,它允许通过索引来访问字符串中的单个字符。

string 类重载了两个operator[],一个是普通版的,一个是 const ,即字符串不可修改的。

简单的测试:

int main()
{
	string s1 = "hello world";

	cout << s1[0] << endl;
	cout << s1[2] << endl;
	cout << s1[4] << endl;

	return 0;
}

输出结果为:

普通版的话我们可以对字符串进行修改。

int main()
{
	string s1 = "hello world";

	s1[0] = 'x';
	s1[1] = 'x';
	s1[2] = 'x';
	cout << s1 << endl;

	return 0;
}

输出结果为:

4.2 at函数

at函数提供了一种安全的方式来访问字符串中的字符。与operator[]不同,at函数会执行范围检查,以确保提供的索引没有超出字符串的当前长度。

int main()
{
	string s1("hello world");
	cout << s1.at(0) << endl;
	cout << s1.at(2) << endl;
	return 0;
}

输出结果为:

4.3 front 和 back 函数

这两个用的比较少,了解即可。

int main()
{
	string s1("hello world");
	cout << s1.front() << endl;
	cout << s1.back() << endl;

	return 0;
}

输出结果如下:

5.string类的修改操作

关于string类的操作修改的接口比较多,由于篇幅有限,实在不能详细一个个讲解,我们就先学习一些比较重要的,其他的有需要再去了解。

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=在字符串后追加字符串str
assign使用指定字符串替换原字符串
replace用新字符串替换原字符串指定区间
pop_back删除字符串最后一个字符
erase删除字符串指定部分
swap交换两个字符串
5.1 字符串增加操作

字符串的增加操作,在末尾添加字符可以使用push_back,在末尾添加字符串可以使用append,而operator+=既可以在末尾添加字符,也可以添加字符串。

int main()
{
    string str("hello world");
    // 追加一个!  
    str.push_back('!');
    cout << str << endl; 

    str += '!';
    cout << str << endl; 

    // 在字符串开头插入一个'!'  
    str.insert(0, 1, '!');
    cout << str << endl; 

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

    str += "world!";
    cout << str << endl; 

    return 0;
}

输出结果为:

5.2 字符串替换操作

字符串替换操作我们用到的是assign和replace。

assign是直接替换掉原字符串,而replace是替换原字符串的某段区间。

示例如下:

int main()
{
    std::string s1("hello world");
    std::string s2;

    s2.assign(s1);
    std::cout << s2 << std::endl;

    s2.assign(s1, 6);
    std::cout << s2 << std::endl;

    // 用s1替换掉下标为2,长度为2的区间
    std::string s3("ciallo");

    s3.replace(2, 2, s1);
    std::cout << s3 << endl;
}

输出结果:

这俩函数接口比较多,可以自行查看文档进行学习。

5.3 字符串删除操作

pop_back支持删除最后一个字符,erase支持删除任意区间。

int main()
{
	string str("hello world");

	str.pop_back();
	cout << str << endl;

	str.erase(str.begin());
	cout << str << endl;

	str.erase(0, 2);
	cout << str << endl;

	return 0;
}

输出结果为:

5.4 字符串交换操作

swap 函数用于交换两个字符串对象的内容。

int main()
{
	string s1("hello world");
	string s2("C++");
	cout << s1 << endl;
	cout << s2 << endl;

	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;
	return 0;
}

输出结果为:

5.5 字符串其他操作

除了以上这些,string类还有很多可以使用的操作。

函数名称功能
c_str返回C格式的字符串
substr从字符串pos位置开始,截取n个字符,然后将其返回
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字串中的位置
find_first_ of在原字符串中,从前往后找匹配串中第一个匹配的字符
find_last_of在原字符串中,从后往前找匹配串中第一个匹配的字符
find_first_not of在原字符串中,从前往后找匹配串中第一个不四配的字符
find_last_not_ of在原字符串中,从后往前找匹配串中第一个不匹配的字符
getline获取一行字符串
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator<<流提取重载
operator>>流插入重载

下面就不展开说了,可以通过查看文档来进行学习。

结束语

本篇博客写的有点长了。。。

希望能对各位大佬有所帮助!!!

求点赞收藏评论关注!!!

感谢各位!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【线程】线程的控制

本文重点&#xff1a;理解线程控制的接口 前言 内核中是没有很明确线程的概念的&#xff0c;只有轻量级进程的概念&#xff0c;不会提供直接给我们线程的系统调用&#xff0c;而会给我们提供轻量级进程的系统调用。我们用户是需要线程的接口的&#xff0c;在应用层&#xff0…

java重点学习-总结

十五 总结 https://kdocs.cn/l/crbMWc8xEZda &#xff08;总结全部的精华&#xff09; 1.面试准备 企业筛选简历规则简历编写注意事项(亮点)项目怎么找&#xff0c;学习到什么程度面试过程(表达结构、什么样的心态去找工作) 2.redis 缓存相关(缓存击穿、穿透、雪崩、缓存过期淘…

智能自行车码表:基于2605C语音芯片的创新开发方案

一、开发背景 随着科技的飞速发展和人们对健康生活的追求&#xff0c;自行车骑行已成为一种广受欢迎的绿色出行方式。智能自行车码表作为骑行者的得力助手&#xff0c;不仅记录骑行数据&#xff0c;还逐渐融入了更多智能化功能。然而&#xff0c;传统码表在语音提示、多语种支持…

Science Robotic 内在触觉实现直观的物理人机交互

触觉传感器和电子皮肤是为机器人提供物理交互感的常见设备&#xff0c;但当用于机器人的大面积覆盖时&#xff0c;它们会变得复杂且昂贵。德国宇航中心近期发表的Science Robotics研究工作&#xff0c;使用内部高分辨率关节力扭矩传感器&#xff0c;在机械臂中实现了固有的全身…

linux网络-----传输层

前言 一.传输层&#xff1a; 数据要交接应用层先通过传输层&#xff08;给哪个程序发数据&#xff09; 传输层作用&#xff1a;负责数据能够从发送端传输接收端。对于应用层来说有许多服务&#xff0c;传输层怎么知道把数据发给那个应用服务&#xff1f; 这时就有了端口号&am…

BMC 虚拟i2c访问PCA9545(switch芯片)后面的设备,为什么找不到PCA9545?

1.说明 1.1 背景 无意中看到PCA9545(switch芯片)后面有设备&#xff0c;但是PCA9545设备本身是连接到物理设备i2c上的&#xff0c;然而扫描该物理i2c bus&#xff0c;却找不到该设备。此篇文章主要找一下该原因的。 1.2 参考代码 当前使用的是ast2600芯片&#xff0c;可参考…

Mudslide

作者未提供代码

Qt/C++ TCP调试助手V1.1 新增图像传输与接收功能(附发布版下载链接)

发布版本链接 通过百度网盘分享的文件&#xff1a;TCP调试助手V1.zip&#xff08;含客户端与服务器&#xff09; 链接&#xff1a;https://pan.baidu.com/s/14LTRPChPhYdwp_s6KeyBiA?pwdcedu 提取码&#xff1a;cedu 基于Qt/C实现了一款功能丰富的TCP服务器与客户端调试助手…

HT876 带任意限幅的10.9Wx2高保真音频功放

特点 可任意配置的限幅功能 自由选择音频限制幅度&#xff0c;使输出音频信号限制在固定 失真水平内 内置自动限温控制功能 支持AB类与D类切换 THDN:0.02%(VDD8.4V, RL 4Ω, fIN 1kHz, Po 2x1.0W, BTL) 输出功率(fIN1kHZ,THDN10%) 2x10.9W (VDD9.0V, RL4Ω, BTL) VDD供电范围:2…

【C++】模拟实现二叉搜索(排序)树

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 二.逐步实现项目功能模块及其逻辑详解 &#x1f4cc;实现BSTreeNode类模板 &#x1f38f;构造BSTreeNode类成员变量 &#x1f38f;实现BSTreeNode类构…

空间解析几何2:空间中两线段/直线的距离【附MATLAB代码】

目录 理论公式 MATLAB代码 理论公式 MATLAB代码 公式实现 function [dis,P,Q,t1,s1]line2LineDistance(A1,B1,C1,D1) %求两线段的最短距离 % input % A1,B1为线段一的两端点 C1,D1为线段二的两端点 % output % dis,为两线段的最短距离&#xff0c;P,Q为距离最短时在两线段上…

10.2 溪降技术:双重检查

目录 10.2 双重检查概览观看视频课程电子书&#xff1a;双重检查场景场景 1场景 2 个人责任示例 1示例 2 总结 10.2 双重检查 概览 俗话说&#xff1a;“江山易改&#xff0c;本性难移”。在我们开始体验峡谷探险时&#xff0c;培养良好的习惯对我们的进一步发展至关重要。在所…

Spring AOP的应用

目录 1、maven坐标配置与xml头配置 2、代理方式的选择与配置 3、AOP的三种配置方式 3.1、XML模式 3.1.1 创建目标类和方法 3.1.2 创建切面 3.1.3 切面xml配置与表达式说明 3.1.4 单测 3.2 纯注解模式 3.2.1 开启注解相关配置 3.2.2 创建目标类和方法 3.2.3 创建切面…

ChatGPT 4o 使用指南 (9月更新)

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

java之斗地主部分功能的实现

今天我们要实现斗地主中发牌和洗牌这两个功能&#xff0c;该如何去实现呢&#xff1f; 1.创建牌类&#xff1a;52张牌每一张牌包含两个属性:牌的大小和牌的花色。 故我们优先创建一个牌的类(Card)&#xff1a;包含大小和花色。 public class Card { //单张牌的大小及类型/…

20240921在友善之臂的NanoPC-T6开发板上使用Rockchip原厂的Android12适配宸芯的数传模块CX6602N

127|console:/ # uname -a console:/ # ifconfig console:/ # ifconfig -a console:/ # ifconfig -a 130|console:/ # ifconfig usb0 192.168.42.130 console:/ # console:/ # ifconfig console:/ # iperf3 -s & iperf3 -c 192.168.42.130 -i 1 -t 30 20240921在友善之臂的…

828华为云征文|华为云Flexus云服务器X实例之openEuler系统下部署Grav内容管理系统

828华为云征文&#xff5c;华为云Flexus云服务器X实例之openEuler系统下部署Grav内容管理系统 前言一、Flexus云服务器X实例介绍1.1 Flexus云服务器X实例简介1.2 Flexus云服务器X实例特点1.3 Flexus云服务器X实例使用场景 二、Grav介绍2.1 CMS介绍2.2 Grav简介2.3 Grav特点2.4 …

TinyML-On-The-Fly: 实时、低功耗、低成本的微控制器嵌入式设备内计算机视觉技术用于无人机图像分类

这篇论文的标题是《TinyML-On-The-Fly: Real-Time Low-Power and Low-Cost MCU-Embedded On-Device Computer Vision for Aerial Image Classification》&#xff0c;作者是 Riya Samanta, Bidyut Saha, Soumya K. Ghosh&#xff0c;来自印度理工学院克勒格布尔分校。论文主要研…

电子元器件之MOS管,附上几个常用MOS管电路和仿真。

MOS管是一种常用的电子元器件。 1.MOS管的类别 MOSFET简称MOS&#xff0c;是一种绝缘栅型场效应管。按照类别可以分为增强型mos管和耗尽型mos管。 导电沟道的形成方式‌ 增强型MOS管&#xff1a;在没有外加电压时&#xff0c;源极和漏极之间没有导电沟道存在。只有当栅极电…

【玉米田】

题目 代码 #include <bits/stdc.h> using namespace std; typedef long long LL;const int mod 1e8; const int M 1 << 12; LL f[13][M]; int g[13]; vector<int> state; vector<int> p[M]; int n, m; bool check(int x) {return !(x & x <&…