【C++String类使用】万字详解保姆级教学,手把手教你使用string类。

news2024/11/23 12:19:20

string类的使用

  • 什么是string类?
  • string构造
    • string();
    • string (const char* s);
    • string (const string& str);
    • string (const string& str, size_t pos, size_t len = npos);
    • string (const char* s, size_t n);
    • string (size_t n, char c);
    • template < class InputIterator >string (InputIterator first, InputIterator last);
  • string类对象的容量操作
    • size
    • length
    • capacity
    • empty
    • clear
    • reserve
    • resize
  • string类对象的访问及遍历操作
    • operator[]
    • iterator迭代器
    • reverse_iterator反向迭代器
    • 范围for
      • 范围for底层实现原理
  • string类对象的修改操作
    • push_back()
    • append()
      • string& append (const string& str);
      • string& append (const string& str, size_t subpos, size_t sublen);
      • string& append (const char* s);
      • string& append (const char* s, size_t n);
      • string& append (size_t n, char c);
    • operator +=
    • c_str()
    • find + npos
  • string类非成员函数
    • getline
    • relational operators (string)字符串比较函数
  • 🍀小结🍀

🎉博客主页:小智_x0___0x_

🎉欢迎关注:👍点赞🙌收藏✍️留言

🎉系列专栏:C++初阶

🎉代码仓库:小智的代码仓库

什么是string类?

C++中的string类是一个字符串容器类,它提供了一系列操作字符串的方法,例如连接、查找、删除、替换等。与C语言中的字符串不同,使用string类可以避免许多重复繁琐的操作,使得代码更加简洁和易于维护。另外,string类支持自动内存管理和动态扩容,可以根据需要动态地调整字符串的大小,这也是其与C语言中的字符数组相比的一个优势。

  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;

我们学习string类需要通过查文档来学习:string类文档介绍

string构造

前面提到了我们学习string类需要结合文档来学习,这里我们在文档中查询string类的构造。
在这里插入图片描述
文档下面也对这几个构造函数有解释>
在这里插入图片描述
在这里插入图片描述

Google翻译>
在这里插入图片描述
在这里插入图片描述

string();

创建一个空的字符串,长度为零个字符。
eg:

int main()
{
	//构造一个空的字符串
	string s1;
	cout << s1 << endl;
	return 0;
}

在这里插入图片描述
可以看到打印出来是空白的。

string (const char* s);

构造一个s字符串的拷贝。
eg:

int main()
{
	//构造一个“hello C++”的字符串
	string s0("hello C++");
	cout << s0 << endl;
	return 0;
}

在这里插入图片描述

string (const string& str);

拷贝构造函数,构造一个str字符串的副本。
eg:

int main()
{
	//构造一个“hello C++”的字符串
	string s0("hello C++");
	//通过s0字符串拷贝构造出s2
	string s2(s0);
	cout << s0 << endl;
	cout << s2 << endl;
	return 0;
}

在这里插入图片描述

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

复制从字符位置pos开始并跨越len个字符的str部分(或者直到str的末尾,如果str太短或者len是string::npos)
eg:

int main()
{
	//构造一个“hello World”的字符串
	string s0("hello World");
	string s3(s0, 8, 3);
	cout << s0 << endl;
	cout << s3 << endl;
	return 0;
}

在这里插入图片描述
这里我们可以发现这个构造函数中有一个缺省值npos,我们可以查看这个npos的定义:
在这里插入图片描述
这里给npos赋值-1,其补码是全1,npos的类型又是size_t(无符号整型)发生了类型转换,把-1强转为size_t类型,所以将-1的补码全1转换为原码,又是无符号类型,所以原反补都相同,此时原码就成为了全1(整型最大值)。
Google翻译>
在这里插入图片描述

string (const char* s, size_t n);

这个构造函数的作用是从s字符串中拷贝前n个字符赋给构造的对象。
eg:

int main()
{
	string s5("C++ is very Good!", 12);
	cout << s5 << endl;

	return 0;
}

在这里插入图片描述

string (size_t n, char c);

用字符c的n 个连续拷贝填充字符串。
eg:

int main()
{
	string s6(10, 'c');
	cout << s6 << endl;
	return 0;
}

在这里插入图片描述

template < class InputIterator >string (InputIterator first, InputIterator last);

范围构造函数
以相同的顺序复制[first,last)范围内的字符序列。
eg:

int main()
{
	string s0("hello C++");
	string s7(s0.begin(), s0.begin() + 7);
	cout << "s0:" << s0 << endl;
	cout << "s7:" << s7 << endl;
	return 0;
}

在这里插入图片描述

string类对象的容量操作

size

在这里插入图片描述
size的功能返回字符串的有效长度,以字节为单位。这是符合字符串内容的实际字节数,不一定等于它的存储容量。
eg:

int main()
{
	string str("hello C++!");
	cout << str.size() << endl;

	return 0;
}

在这里插入图片描述

length

在这里插入图片描述
length的功能与size的功能相同,都是返回字符串的有效长度。
eg:

int main()
{
	string str("hello C++!");
	cout << str.size() << endl;
	cout << str.length() << endl;

	return 0;
}

在这里插入图片描述

capacity

在这里插入图片描述
返回当前为string 分配的存储空间的大小,以字节表示。
容量不一定等于字符串长度。它可以等于或更大,额外的空间允许对象在新字符添加到 string 时优化其操作。
我们在vs2019编译器下编译运行以下代码>

int main()
{
	string str("hello C++!");
	cout << str.size() << endl;
	cout << str.length() << endl;
	cout << str.capacity() << endl;
	cout << str.max_size() << endl;


	return 0;
}

在这里插入图片描述
可以看到capacity比实际的大小要大一点。
我们再来在g++编译器来运行上面的代码>
在这里插入图片描述
我们能看到g++编译器下的capacity和size的大小是相同的,两款编译器下的max_size也是不一样的,所以我们在平时几乎不会用max_size()。(max_size返回的是字符串可达到的最大长度)

empty

在这里插入图片描述
测试字符串是否为空
返回字符串是否为空(即它的长度是否为0)
如果字符串长度为0则为true,否则为false。

clear

在这里插入图片描述
清除字符串
擦除string 的内容,它变成一个空字符串(长度为0个字符)。

reserve

在这里插入图片描述
reserve(size_t n=0):为string预留空间,不改变有效元素个数,当reserve的参数小于
string的底层空间总大小时,reserver不会改变容量大小。

resize

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

注意:

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。

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

operator[]

在这里插入图片描述
他的功能是可以返回pos位置的字符,也就是说可以通过 [ ] 来访问字符串中的某一个字符。
eg:

int main()
{

	string str("hello C++");
	cout << str << endl;

	for (int i = 0; i < str.size(); i++)
	{
		cout << str[i];
	}
	cout << endl;
	return 0;
}

在这里插入图片描述
可以看到我们通过str[i]也可以对str字符串进行遍历输出。
他也有函数重载,一个是被const修饰的一个不能被修改,一个没有被const修饰可以进行修改。这里我们举个栗子>
我们对一个字符串的每个字符都进行++处理,再来打印:

int main()
{

	string str("hello C++");
	cout << str << endl;
	//对字符串的每个字符进行++
	for (int i = 0; i < str.size(); i++)
	{
		str[i]++;
	}
	//通过[]对字符串进行遍历
	for (int i = 0; i < str.size(); i++)
	{
		cout << str[i];
	}
	cout << endl;

	return 0;
}

在这里插入图片描述
可以看到我们把原本的字符串进行了修改,当然如果是一个const修饰的对象调用operator[ ],他就会调用const修饰的operator[ ]函数,被const修饰的对象当然也不能被改变。

iterator迭代器

我们来看这样一段代码>

int main()
{
	string s1("hello C+++");

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

其中s1.begin()是指向的字符串的第一个字符,s1.end()指向的是最后一个字符的下一个。
在这里插入图片描述
可以看到这个函数的功能是:
将迭代器返回到开头
返回指向字符串第一个字符的迭代器。

在这里插入图片描述
返回迭代器结束
返回指向字符串的结尾字符的迭代器。

理解了这两个迭代器函数。我们来运行上面代码看结果>
在这里插入图片描述
注:itertor是像指针一样的类型,有可能是指针,有可能不是指针。 具体是什么,我们以后再来探讨。
迭代器也是可以对数据进行修改的

int main()
{
	string s1("hello C++");
	cout << s1 << endl;
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		//通过迭代器对s1中的字符进行--
		(*it)--;
		++it;
	}
	/让s1.begin()重新指向开头位置
	it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

reverse_iterator反向迭代器

如果想要倒着打印字符串也可以通过反向迭代器来进行操作>

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

上面代码中的s1.rbegin()返回反向迭代器到反向开始,返回指向字符串最后一个字符,s1.rend()返回反向迭代器到反向结束返回指向字符串第一个字符之前的理论元素的反向迭代。
在这里插入图片描述
rbegin() 返回一个反向迭代器,指向 string 对象中最后一个字符。
在这里插入图片描述
rend()返回一个反向迭代器,指向 string 对象中第一个字符之前的位置。

了解了上面两个函数我们再来运行上面代码看结果>
在这里插入图片描述

范围for

C++11支持更简洁的范围for的新遍历方式

使用方法也是很简单,来看一段代码>

int main()
{
	string s1("hello C++");
	//for(char& ch : s1)
	for (auto& ch : s1)
	{
		cout << ch;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述
上面for (auto& ch : s1)的意思是依次取出s1中的字符传给ch,再对ch进行打印。auto是自动识别类型,当然我们也可以写成for (char& ch : s1),在我们日常中经常使用auto自动识别类型。
当然也可以通过范围for对字符串中的内容进行修改。

int main()
{
	string s1("hello C++");
	for (auto& ch : s1)
	{
		ch++;
	}
	for (auto& ch : s1)
	{
		cout << ch;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

范围for底层实现原理

范围for底层其实就是调用使用迭代器来完成>
在这里插入图片描述
通过反汇编代码我们可以看到在我们使用范围for的时候调用了两个迭代器函数,分别是begin()和end()。

string类对象的修改操作

push_back()

在这里插入图片描述
将字符附加到字符串
将字符c附加到字符串的末尾,将其长度增加一。

int main()
{
	string str("hello C+");
	cout << str << endl;
	str.push_back('+');
	cout << str << endl;
	return 0;
}

在这里插入图片描述

append()

在这里插入图片描述
附加到字符串
通过在当前值的末尾附加额外的字符来 扩展字符串:

append也重载了许多个函数。我们这里介绍几个比较常用的。

string& append (const string& str);

这个函数的功能是追加str的拷贝。
eg:

int main()
{
	string str1("hello ");
	string str2("C++");
	str1.append(str2);
	cout << str1 << endl;
	return 0;
}

在这里插入图片描述

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

追加str的子字符串的副本。子字符串是str的一部分,它从字符位置subpos开始并跨越sublen个字符(或者直到str的结尾,如果str太短或者sublen是string::npos)。
eg:

int main()
{
	string str1("hello ");
	string str2("C++");
	str1.append(str2,0,2);
	cout << str1 << endl;
	return 0;
}

在这里插入图片描述
从str2的第0个位置开始追加追加两个字符。

string& append (const char* s);

在字符串后面追加一个字符串。
eg:

int main()
{
	string str1("hello ");
	str1.append("C++");
	cout << str1 << endl;
	return 0;
}

在这里插入图片描述

string& append (const char* s, size_t n);

在s指向的字符数组中追加前n个字符的副本。
eg:

int main()
{
	string str1("hello ");
	str1.append("C++! hello",3);
	cout << str1 << endl;
	return 0;
}

在这里插入图片描述
在str后面追加"C++ hello"字符串中的前三个字符。

string& append (size_t n, char c);

填充
追加字符c的n 个连续拷贝。

eg:

int main()
{
	string str1("hello C");
	str1.append(2,'+');
	cout << str1 << endl;
	return 0;
}

在这里插入图片描述

operator +=

在这里插入图片描述
这个重载也是字符串追加的功能。可以追加string对象,可以追加字符串,也可以追加单个字符。
eg:

int main()
{
	string name("John");
	string family("Smith");
	name += " K. ";         // c-string
	name += family;         // string
	name += '\n';           // character

	cout << name;
	return 0;
}

在这里插入图片描述

c_str()

在这里插入图片描述
c_str()string 类的成员函数,用于返回一个指向 string 对象中第一个字符的指针。该指针指向的字符数组以空字符结尾,可以用于与 C 风格字符串进行交互。以下是 c_str() 的用法和示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "hello";
    const char *cstr = str.c_str();
    std::cout << cstr << std::endl; // hello
    return 0;
}

在上面的示例中,我们首先创建了一个 string 对象 str,然后使用 c_str() 函数将其转换为 C 风格字符串,并将返回的指针存储在 const char *cstr 中。最后,我们使用 std::cout 输出了 cstr 指向的字符数组。需要注意的是,由于 c_str() 返回的指针指向的字符数组是以空字符结尾的,因此可以使用该指针与 C 风格字符串进行交互。

find + npos

在这里插入图片描述
在这里插入图片描述
find()string 类的成员函数,用于在字符串中查找指定的子串,并返回其位置。nposstring 类的静态成员变量,表示未找到指定子串时的返回值。以下是 find()npos 的用法和示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "hello world";
    std::string sub = "world";
    std::size_t pos = str.find(sub);
    if (pos != std::string::npos) {
        std::cout << "Substring found at position " << pos << std::endl;
    } else {
        std::cout << "Substring not found" << std::endl;
    }
    return 0;
}

在上面的示例中,我们首先创建了一个 string 对象 str,然后使用 find() 函数查找字符串 "world"str 中的位置,并将返回值存储在 pos 中。接着,我们使用 if 语句判断 pos 是否等于 std::string::npos,如果不等于,则说明找到了子串,输出其位置;否则说明未找到子串,输出提示信息 "Substring not found"

需要注意的是,find() 函数可以接受一个可选的参数,用于指定搜索起始位置。例如,如果我们想从 str 的第 7 个字符开始查找子串,可以将其作为 find() 函数的第二个参数传入:

std::size_t pos = str.find(sub, 7);

这样就会从第 7 个字符开始查找子串。

另外,需要注意的是,npos 的值是一个特殊值,表示未找到指定子串时的返回值。它的值是一个无符号整数,通常是一个非常大的数值,因此可以用于判断 find() 函数是否查找到了指定子串。
注意:

  1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般
    情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

string类非成员函数

我们上面一直在使用cout<<str<<endl;在对字符串进行打印输出,string不是内置类型,为什么还可以使用输出<<打印呢?
这是因为string类外面重载了operator<<(string)和operator>>(string)。
在这里插入图片描述
将字符串插入流
将符合str 值的字符序列插入到os中。
此函数重载operator<<使其行为如ostream::operator<<中所述,适用于 C 字符串,也适用于字符串对象。

在这里插入图片描述
从流中提取字符串
从输入流is中提取一个字符串,将序列存储在str中,它被覆盖( str的先前值被替换)。
此函数重载operator>>使其行为如istream::operator>>中描述的用于 c 字符串,但应用于字符串对象。
每个提取的字符都附加到字符串,就好像它的成员push_back被调用一样。

getline

在这里插入图片描述
getline 是 C++ 中 string 类的一个成员函数,用于从输入流中获取一行数据。它的使用方法如下:

int main() {
	string name;
	cout << "请输入你的名字>";
	getline(cin, name);
	cout << "Hello " << name << endl;
	return 0;
}

在这里插入图片描述
在上面的例子中,我们使用 getline 从标准输入流 std::cin 中读取一行数据,并将其存储到 line 变量中。然后,我们将这个字符串输出到标准输出流 std::cout 中。
也可以指定一个分隔符来代替默认的换行符 \n。例如,如果你想使用逗号作为分隔符,可以这样写:

int main() {
	std::string name;
	std::cout << "请输入你的名字>";
	std::getline(std::cin, name, ',');
	std::cout << "Hello " << name << std::endl;
	return 0;
}

在这里插入图片描述
在上面的例子中,我们使用逗号作为分隔符来读取输入流中的一行数据。

relational operators (string)字符串比较函数

在这里插入图片描述
relational operatorsstring 类的比较运算符,用于比较两个 string 类型的对象。
以下是 relational operators 的用法和示例:

  1. == 运算符:判断两个 string 对象是否相等,如果相等则返回 true,否则返回 false
#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "hello";
    std::cout << std::boolalpha << (str1 == str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 == str3) << std::endl; // true
    return 0;
}
  1. != 运算符:判断两个 string 对象是否不相等,如果不相等则返回 true,否则返回 false
#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "hello";
    std::cout << std::boolalpha << (str1 != str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 != str3) << std::endl; // false
    return 0;
}

  1. < 运算符:判断一个 string 对象是否小于另一个 string 对象,如果是则返回 true,否则返回 false
#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 < str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 < str3) << std::endl; // false
    return 0;
}

  1. > 运算符:判断一个 string 对象是否大于另一个 string 对象,如果是则返回 true,否则返回 false
#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 > str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 > str3) << std::endl; // true
    return 0;
}

5.<= 运算符:判断一个 string 对象是否小于或等于另一个 string 对象,如果是则返回 true,否则返回 false

#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 <= str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 <= str3) << std::endl; // false
    return 0;
}
  1. >= 运算符:判断一个 string 对象是否大于或等于另一个 string 对象,如果是则返回 true,否则返回 false
#include <iostream>
#include <string>

int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 >= str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 >= str3) << std::endl; // true
    return 0;
}

上面的几个接口大家了解一下,string类中还有一些其他的操作,这里不一一列举,大家在需要用到时不明白了查文档即可。

🍀小结🍀

今天我们认识了C++string类的用法相信大家看完有一定的收获。
种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!创作不易,辛苦各位小伙伴们动动小手,三连一波💕💕~~~,本文中也有不足之处,欢迎各位随时私信点评指正!
本节课的代码已上传gitee仓库!

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

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

相关文章

《The Element of Style》阅读笔记 —— 章节 III A Few Matters of Form

前言&#xff1a;本篇为书籍《The Element of Style》第三章的阅读笔记。 本书电子版链接&#xff1a;http://www.jlakes.org/ch/web/The-elements-of-style.pdf 章节 I Elementary Rules of Usage 阅读笔记&#xff1a;链接章节 II Elementary Principles of Composition 阅读…

JavaScript进阶之路(一)初学者的开始

一&#xff1a;写在前面的问题和话 一个javascript初学者的进阶之路&#xff01; 背景&#xff1a;3年后端&#xff08;ASP.NET&#xff09;工作经验&#xff0c;javascript水平一般般&#xff0c;前端水平一般般。学习资料&#xff1a;犀牛书。 如有误导&#xff0c;或者错…

Git日常使用技巧 - 笔记

Git日常使用技巧 - 笔记 Git是目前世界上最先进的分布式版本控制系统 学习资料 廖雪峰 学习视频 https://www.bilibili.com/video/BV1pX4y1S7Dq/?spm_id_from333.337.search-card.all.click&vd_source2ac127043ccd79c92d5b966fd4a54cd7 Git 命令在线练习工具 https://l…

多线程 -- Thread类的基本用法

本篇重点 什么是变量捕获?? 有关线程的操作 线程创建线程中断线程等待线程休眠获取线程实例目录 1. 线程创建2. 线程中断变量捕获 线程的六种状态NEW 状态TERMNATED 状态RUNNABLE 就绪状态TIMED_WAITING 状态 1. 线程创建 关于线程的创建看上篇博客, 里面为线程的创建提供…

数据库事务到底是什么?

目录 场景&#xff08;两个用户之间进行转账操作&#xff09;&#xff1a; 需要的操作步骤&#xff1a; 事务 事务的四大特性&#xff1a; 一、原子性 &#xff08;1&#xff09;什么是回滚操作 &#xff08;2&#xff09;数据库恢复操作&#xff0c;如何知道数据恢复如初…

C++ Stack&queue&deque

C Stack&#xff06;queue&#xff06;deque &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容主要讲解了栈和…

如何在华为OD机试中获得满分?Java实现【字符串通配符】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1、题目描述2、输入描述3、输出描述…

Rust 笔记:Rust 语言中应用正则表达式

Rust 笔记 Rust 语言中应用正则表达式 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/…

【Linux】线程详解之线程互斥与同步

文章目录 Linux线程互斥一、进程线程间的互斥相关概念1.临界资源和临界区2.互斥和原子性 二、互斥量mutex1.抢票程序是否引入互斥量现象观察2.抢票程序原理分析3.互斥量的接口4. 加锁后的程序5.互斥量原理探究 可重入VS线程安全一、概念1.线程安全2.重入 二、常见的线程不安全的…

【P37】JMeter 仅一次控制器(Once Only Controller)

文章目录 一、仅一次控制器&#xff08;Once Only Controller&#xff09;参数说明二、测试计划设计2.1、测试计划一2.1、测试计划二 一、仅一次控制器&#xff08;Once Only Controller&#xff09;参数说明 可以让控制器内部的逻辑只执行一次&#xff1b;单次的范围是针对某…

Spring Authorization Server 系列(一)环境搭建

Spring Authorization Server 中的scope参数解析 前提依赖版本问题确定Spring Boot 版本确定 Spring Authorization Server 版本最终的依赖 第一个 Spring Authorization Server Demo 前提 由于 Spring 最新的 OAuth2 解决方案 已经由 Spring Security 下的 OAuth2 模块独立出…

从零开始学习JavaScript:轻松掌握编程语言的核心技能①

从零开始学习JavaScript&#xff1a;轻松掌握编程语言的核心技能 一&#xff0c;JavaScript 简介为什么学习 JavaScript?JavaScript 用法 二&#xff0c;JavaScript 输出JavaScript 显示数据JavaScript&#xff1a;直接写入 HTML 输出流 三&#xff0c;JavaScript 语法JavaScr…

VS2022发布独立部署的.net程序

.net core支持依赖框架部署和独立部署两种方式&#xff0c;之前学习时是在VSCode中使用dotnet命令发布的。但是在VS2022中却不知道该如何设置。以获取PDF文件使用字体的项目为例&#xff0c;VS2022中默认编译的是依赖框架部署方式&#xff08;编译的结果如下图所示&#xff09;…

Android进阶 View事件体系(三):典型的滑动冲突情况和解决策略

Android进阶 View事件体系&#xff08;三&#xff09;&#xff1a;典型的滑动冲突情况和解决策略 内容概要 本篇文章为总结View事件体系的第三篇文章&#xff0c;前两篇文章的在这里&#xff1a; Android进阶 View事件体系&#xff08;一&#xff09;&#xff1a;概要介绍和实…

Oracle——数据操纵DML(一)

STU1 1、不指定字段的整行插入 在STU1中新增一名同学的基本信息&#xff0c;SQL如下&#xff1a; INSERT INTO test.stu1 VALUES(0001,牛牛,男,24,to_date(1988-05-25,YYYY-MM-DD),12外语)格式如下&#xff1a; INSERT INTO 表名 VALUES(值1,值2,...,值n)对于CHAR或VARCHAR等…

sql-labs SQL注入平台——第二关Less-2 GET - Error based - Intiger based (基于错误的GET整型注入)

Less-2 GET - Error based - Intiger based (基于错误的GET整型注入) 一、先确认漏洞是否存在 &#xff08;1&#xff09;查询 id1返回查询结果正常 &#xff08;2&#xff09;查询 id1’返回查询结果报错&#xff0c;可能存在SQL注入 &#xff08;3&#xff09;查询 id1 …

路径规划算法:基于帝国主义竞争优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于帝国主义竞争优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于帝国主义竞争优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用…

Dubbo环境搭建

1.搭建zookeeper注册中心环境 zookeeper下载地址 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ptMw7rb-1685261782669)(b894c0cbb6501ca97145d3b09685ae8f.png)] 在bin文件下&#xff0c;启动zkServer.cmd会有报错&#xff0c;处理需要在condi…

你所不知道的 数据在内存中储存 的来龙去脉

那么好了好了&#xff0c;宝子们&#xff0c;今天给大家介绍一下 “数据在内存中储存” 的来龙去脉&#xff0c;来吧&#xff0c;开始整活&#xff01;⛳️ 一、数据类型的介绍 &#xff08;1&#xff09;整型和浮点型&#xff1a; &#xff08;2&#xff09;其他类型…

Linux——使用命令行参数管理环境变量

目录 使用命令行参数获取用户在DOS命令行输入的指令&#xff1a; 方法&#xff1a;代码如下&#xff1a; 使用命令行参数获取并打印部分或者整体环境变量的方法&#xff1a; 方法1&#xff1a; 运行结果&#xff1a; 方法2&#xff1a;使用外部链接environ: 使用命令行参数…