完整教程:【C++】string类的常见接口的使用

news/2025/9/28 20:02:34/文章来源:https://www.cnblogs.com/slgkaifa/p/19117494

完整教程:【C++】string类的常见接口的使用

欢迎拜访:Madison-No7个人主页
文章主题:string类的常见接口的使用
隶属专栏:我的C++成长日志
写作日期:2025年9月27号

目录

一、初识string

二、string类的常见接口的使用

2.1 string的构造函数

2.2 string 的析构函数

2.3 string的常见容量接口

2.4 遍历string中的元素

(1)operator[]

(2)Iterator 迭代器

(3)范围for(C++11支持):

补充知识:auto关键字

2.5 与对象修改有关的操作

2.6 与查找有关的接口

2.7 string类的非成员函数


一、初识string

  1. string是表示字符串的字符串类,可以理解为字符顺序表
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3.  string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
  4. 不能操作多字节或者变长字符的序列。

注意:使用string类时,必须包含#include<string>以及using namespace std;

二、string类的常见接口的使用

2.1 string的构造函数

默认构造string()

说明:构造一个长度为0个字符的空字符串。

字符串构造string:string (const char* s)

说明:用C-string来构造string类对象。

拷贝构造string (const string& str)

说明: 使用一个string对象拷贝构造一个新的string对象             

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

说明:拷贝str中从字符位置pos开始并跨越len个字符的部分(如果str太短len为string::npos,复制到str的末尾)。

注意:string对象的第一个有效字符的下标是0。

其中string::npos是string类中的静态成员变量,默认为-1,因为它是size_t类型,实际上就是整型的最大值了,大概是42亿多字节,4G左右,一个string对象不会有4G那么大,所以npos完全够用。如果在调用时,不显示设置len的值,那就从pos开始复制到str的末尾。

不显示设置len:

显示设置len:

初始化字符串s前n个字符:string (const char* s, size_t n)

初始化n个字符C:string(size_t n, char c)

2.2 string 的析构函数

销毁字符串对象。

2.3 string的常见容量接口

size()/length()

返回字符串有效字符的长度(不包含'\0'),以字节为单位。

string s1("hello world");
cout << s1.size() << endl;//推荐使用size
cout << s1.length() << endl;//length也可以求字符串长度,为了更好的兼容C语言

capacity()

返回当前为字符串分配的存储空间(不包含'\0'的大小,表示能存多少个有效字符不算\0,以字节表示。

string s1("hello world");
cout << s1.capacity() << endl;

为什么s1的容量是15呢?就需要来看看capacity的扩容机制了。

capacity扩容机制:

写一个测试容量变化的代码,向一个对象中循环插入字符,只要容量变了就打印来看看。

VS2022下运行:

void testcapacitygrow()
{string s;size_t sc = s.capacity();cout << "0个字符的string容量:" << sc<

实际上开的空间要多一个字节,多的一个字节是'\0','\0'不算作有效的空间。

所以我们不难发现,第一次是2倍扩,后续就是1.5倍扩了。

VS在底层做了特殊的处理,当所需要的空间小于16字节时,会把字符串存到栈上buf的数组里。大于16字节时,此时buf数组废弃不用了,会去堆上开辟一块空间,存到堆上。

Vs下,string的结构:

union _Bxty
{ // storage for small buffer or pointer to larger onevalue_type _Buf[_BUF_SIZE];pointer _Ptr;char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

string这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建

好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。

把同样的代码放在linux下用g++编译并运行:

可见在Linux下,是标准的2倍扩容。

小Tips:在不同的编译器下,扩容机制是不一样的。

reserve(size_t n=0)

为了避免频繁的扩容,用reserve()可以提前开辟空间,也就是在内存中预留n个空间,避免后续的频繁扩容,提高效率。

也就是我们中午去学校食堂吃饭,人很多,你去的时候,占下一个位置,别人看来就是这个位置有人了,当你打完饭,就直接可以到你占的位置就餐,就不需要找位置了,节约了一些时间,也就是提高了效率。

Vs下提前开100个字节的空间,但是开了比100大的空间。

g++下就是要100就给100,但是有些时候,为了内存对齐,会多一些空间。

小Tips:所以在不同的编译器下,所预留的空间大小是不确定的,但是一定大于你想要预留空间的大小n。

注意:返回string开辟或预留的空间的大小都不包含\0,实际在底层开的空间大小都要大一个字节,以存储'\0'。也就是说在Vs下预留空间111,实际上在底层是112字节。

那reserve()会不会缩容呢?

我们假设给一个字符串长度为20,容量为31,当reserve(n)中n<20时,是不会缩容的,因为这个函数不能影响string的长度和内容。当20<n<31,是不确定的,不同的编译器情况是不同的,当n>31时,会扩容。

在Vs2022编译器下调试缩容情况:以下是测试代码

void test_reserve()
{string s("12345678919876543219");cout << "size:" << s.size() << endl;cout <<"capacity:" << s.capacity() << endl;s.reserve(15);cout << "n<20时,容量为:" << s.capacity() << endl;s.reserve(25);cout << "20

我们假设给一个字符串长度为20,容量为31,测试预留不同的空间(n),缩容的情况;

可见VS2022的策略是:预留空间(n)小于capacity时,容量就不变化,大于预留空间(n)时,就扩容。

来看看在Linux操作系统的g++编辑器下的情况:一样的测试代码

可见在g++编辑器下,reserve()不会缩容

小Tips:所以在VS和g++下,都不会缩容。

2.4 遍历string中的元素

有三种方法:

(1)operator[]

表示获取字符串的字符;

s1[0]会去调用operator[]函数,参数为字符串pos位置的下标,返回的是 pos位置字符的引用,因为string中的字符是存在堆上的,出函数不会销毁。operator[]能获取pos位置的字符,对于普通对象,指定字符串的下标能修改该位置的值。该函数的越界检查是断言检测。

既然operator[]能获取pos位置的字符,我们就能像用数组一样,遍历string中的内容。

(2)Iterator 迭代器

迭代器(Iterator) 是一种用于遍历容器(如vectorlistmap等)中元素的对象,它提供了统一的访问接口,使得开发者可以不依赖容器的具体实现来操作元素。

迭代器的作用类似于指针,但比指针更通用 —— 它可以适配不同的数据结构(数组、链表、树等),让遍历操作变得一致。

迭代器体现了封装的思想,因为它屏蔽了底层的实现细节,提供了统一的类似访问容器的方式,不需要关心容器底层结构和实现的细节。

小Tips:迭代器用于遍历和访问容器的。掌握了迭代器,就可以访问所有的容器。

begin():

表示返回一个指向字符串第一个字符的迭代器。

end():

表示返回一个指向字符串末尾的下一个字符的迭代器。

rbegin():

表示返回一个指向字符串最后一个字符的反向迭代器(即它的反向开头)。

rend():

返回一个反向迭代器,指向字符串第一个字符前面的理论元素(被认为是字符串的反向结束)。

cbegin():

表示返回指向字符串第一个字符的const_iterator

cend():

表示返回一个const_iterator,指向字符串的后结束字符

crbegin():

表示返回一个const_reverse_iterator,指向字符串的最后一个字符。

crend():

表示返回一个const_reverse_iterator,指向字符串第一个字符前面的理论字符。

正向迭代器访问string:可读可写

string s1("hello world");
//it类似于指针
string::iterator it = s1.begin();
while (it!=s1.end())
{cout << *it << " ";it++;
}

it接收的是指向s1对象的字符串首字符的迭代器。*it类似于指针的解引用,it++类似于指针的移动,这里的*和++都做了运算符的重载,关于如何重载的,后续再做讲解。

此外,普通迭代器可以修改。但是const修饰的迭代器就只能读,不能写了。

反向迭代器访问string:(倒着遍历)可读可写

string s1("hello world");
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{cout << *rit << " ";rit++;//注意这里还是++,反向即倒着走
}

const正向迭代器访问string:只能读,不能写

用于遍历常量字符串

const string s2(s1);
string::const_iterator cit = s2.cbegin();//s2.cbegin()返回const迭代器
while (cit!= s2.cend())
{cout << *cit << " ";cit++;
}

类似于const int * a,自己的指向能修改,指向的内容不能修改。

注意:cbegin()和cend()得匹配使用。

const反向迭代器访问string:只能读,不能写

用于遍历常量字符串

string::const_reverse_iterator crit = s2.crbegin();
while (crit != s2.crend())
{cout << *crit << " ";crit++;//注意这里还是++,反向即倒着走
}
cout << endl;

注意:const_reverse_iterator 是一个类型,他们之间使用_连接。

(3)范围for(C++11支持):

//自动复制,自动迭代,自动判断结束
string s1("hello world");
for (auto ch : s1)
{cout << ch << " ";
}

auto ch : s1 表示:从字符串s1中依次取出每个字符,赋值给变量chauto会自动推导出ch的类型为char),auto下面会具体讲解。

for循环后的括号由冒号分为两部分:第一部分是范围 内用于迭代的变量,第二部分则表示被迭代的范围。

范围for的特点:自动复制,自动迭代,自动判断结束

  1. 自动迭代:无需手动获取迭代器或控制索引,自动从容器第一个元素遍历到最后一个元素。
  2. 自动复制:自动将遍历到的字符拷贝给迭代变量(上面是ch)。
  3. 自动判断结束:当遍历字符串的\0时,自动结束。

若需要修改原字符串中的字符,应使用引用类型。

string s1("hello world");
for (auto& ch : s1)
{cout << ch << " ";
}

若只需读取元素(不修改),建议用 const 引用:for (const int& num : nums)避免不必要的拷贝,提高效率。

string s1("hello world");
for (const auto& ch : s1)
{cout << ch << " ";
}

范围for与迭代器的关系

范围 for 循环的底层实现依赖容器的迭代器(调用begin()和 end()获取范围),因此自定义容器若要支持范围 for,需实现begin() 和 end()方法并返回合法迭代器。

建议使用情景:

范围 for 循环特别适合需要完整遍历容器无需手动控制索引 / 迭代器的场景,能显著简化代码,是 C++ 中推荐的遍历方式之一。

补充知识:auto关键字

  • auto 是一个类型说明符,主要作用是自动推导变量的类型,让编译器根据初始化表达式的类型来确定变量的具体类型,从而简化代码书写并提高灵活性。
int main()
{auto b = 10;auto c = 'a';cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;return 0;
}

编译器在编译时期, 根据等号右侧的值推断变量类型。其中typeid().name() 是用于获取类型名称的机制。

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

  • 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
//编译器报错,变量q和w类型不同,"auto"必须推倒同一类型
//auto q = 20, w = 20.0;
  • auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
  • auto不能直接用来声明数组

auto用武之地:简化代码

const string s2(s1);
//传统写法,类型冗长
//string::const_iterator cit = s2.cbegin();
// 使用auto:自动推导为迭代器类型
auto cit = s2.cbegin();
while (cit!= s2.cend())
{cout << *cit << " ";cit++;
}

2.5 与对象修改有关的操作

特别说明:operator+=在以后用的比较多,其他的要用的时候,查查文档即可。

(1)operator =

 表示为当前字符串赋一个新值,替换其当前内容。

int main()
{string s1("hello world");string s2("你好,世界");//将一个string对象赋值给另一个对象s2 = s1;cout << s2 << endl;//将一个字符串赋值给已存在的string对象s2 = "你好,C++";cout << s2 << endl;//将一个字符赋值给已存在的string对象s2 = 'c';cout << s2 << endl;return 0;
}

(2)void push_back(char c)

表示将字符c追加到字符串的末尾,使其长度增加1。

(3)append

表示追加一个字符串的拷贝到当前string对象

void test07()
{string s1("hello ");string s2("world!");cout << "追加前的string->" << s1 << endl;s1 = "hello";s1.append(s2);cout << "追加一个string对象的拷贝->" << s1 << endl;s1 = "hello";s1.append(s2,1,3);cout << "追加一个string对象的拷贝,从下标为1处开始,跨越3个字符->" << s1 << endl;s1 = "hello";s1.append("C++");cout << "追加一个字符串C++->" << s1 << endl;s1 = "hello";s1.append("C++",1);cout << "追加一个字符串C++的前1个字符->" << s1 << endl;s1 = "hello";s1.append(5, 's');cout << "追加5个字符s->" << s1 << endl;
}

(4)operator+=

表示在当前对象的末尾追加字符串来扩展字符串。

void test08()
{string s1 = ("hello ");string s2 = ("world");cout << "追加前->" << s1 << endl;s1 = "hello ";s1 += s2;cout << "追加string对象的拷贝->" << s1 << endl;s1 = "hello ";s1 += "world";cout << "追加字符串s->" << s1 << endl;s1 = "hello ";s1 += 'c';cout << "追加字符c->" << s1 << endl;
}

小Tips:

append()和operator+=都是追加字符串的,说明C++在这里设计的有点冗余了,追加字符使用operator+=相对来说更方便一些。

(5)erase

表示删除字符串的一部分,减少其长度。可间接实现头删,尾删,任意位置的删除。

void test09()
{string s1("hello");cout << "删除前->" << s1<" << s1 << endl;s1 = "hello";s1.erase(s1.begin());cout << "删除第一个位置的字符->" << s1 << endl;s1 = "hello";s1.erase(++s1.begin(),--s1.end());cout << "删除[1,最后一个元素)范围的字符串->" << s1 << endl;
}

小Tips:

频繁的插入和删除会影响效率,因为string就相当于动态顺序表,会涉及到挪动数据。

(6)push_back

void push_back (char c);

表示在字符串后尾插字符C;此外,与之相对的是pop_back,表示删除字符串的最后一个字符。

除了上面介绍的一些常用的字符串修改接口外,还有一些不太常用的,例如:assign(内容替换)、insert(指定位置插入)、erase(删除)、replace(部分替换)、swap(交换两个字符串),它们的使用方法都大同小异。

值得注意的是insert、erase、replace要谨慎使用,它们都是性能杀手。因为如果你频繁调用它们,可能会频繁扩容和挪动数据。

2.6 与查找有关的接口

(1)find

从字符串的pos位置开始往后查找字符或字符串,返回其在当前字符串中的位置

void test10()
{string s1("The secret of success is constancy to purpose.");string s2("success");size_t a=s1.find(s2,0);cout <<"从0位置开始找,第一次找到s2对象的内容的下标是:"<< a << endl;size_t b = s1.find("constancy",14);cout << "从下标为14位置开始找,第一次找到“constancy”的下标是:" << b << endl;size_t c = s1.find("constancy",14,5);cout << "从下标为14位置开始找,第一次找到“constancy”的前5个字符的下标是:" << c << endl;size_t d = s1.find('z',14);cout << "从下标为14位置开始找,第一次找到'z'的下标是:" << d << endl;
}

注意:该函数的返回值是第一个匹配的第一个字符的位置。如果没有找到匹配项,函数返回string::npos。npos表示整型最大值。

(2)c_str

const char* c_str() const;

返回一个指向字符串对象的指针,该字符串对象包含一个以空结尾的字符序列(即C-string),返回值类型是const char*。

void test11()
{string s1("hello C++");const char* str=s1.c_str();cout << str << endl;cout << (const void*)str << endl;printf("%p",str);
}

c_str的返回值是const char*指针类型,那str打印应该是地址呀?为什么是字符串呢?

原因是:C++ 的输出流std::cout对 char* 或const char*类型的指针做了重载处理,对于其他类型指针(如 int*void* 等),默认输出地址。当检测到指针指向的是字符类型时,它会默认将其视为C 风格字符串(以 \0结尾的字符序列),并从指针指向的位置开始,依次输出字符,直到遇到字符串结束符 \0为止。这是为了方便字符串的输出,符合日常使用习惯。

如果想打印指针的地址:需要通过强制类型转换,将 const char*转为无类型指针const void*cout 对 void* 类型会输出地址。

c_str接口的作用:

许多 C 语言库函数(如 strlenstrcmpprintf 等)或遵循 C 风格的 API 要求传入以 \0 结尾的 const char* 类型字符串。c_str() 提供了从 C++ string 到 C 风格字符串的转换,实现了两种字符串类型的兼容。

#include
#include
using namespace std;
int main()
{string s1 = "hello C++";//使用C语言的printf输出,需要C风格字符串printf("%s\n",s1.c_str());//hello C++return 0;
}

(3)substr

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

表示在str中从pos位置开始,截取n个字符,然后将其返回。len不指定时,默认为整型最大值。

该接口常与find和rfind接口使用。

(4)rfind

表示从字符串pos位置开始往前查找字符或字符串,返回该字符或字符串在调用的字符串对象中的位置。

比如我们要在"C:\Users\Administrator\Desktop"这样一个路径中取出Desktop,就可以用到find。

但是得注意路径中的反斜杠,需要使用双反斜杠 \\(第一个 \ 用于转义第二个 \,使其被视为普通字符)。

void test12()
{string s1="C:\\Users\\Administrator\\Desktop";size_t pos=s1.rfind('\\');string SubStr = s1.substr(pos);cout << SubStr << endl;
}

小Tips:

除了上面介绍的一些常用接口,还有一些不常用的,比如:find_first_of(在字符串中搜索与其参数中指定的任何字符匹配的第一个字符)、find_last_of(查找最后一个匹配的)、find_first_not_of(查找第一个不匹配的)、find_last_not_of(查找最后一个不匹配的)。

个人认为把find_first_of改成find_any_of,find_last_of改为rfind_any_of这样好理解一点。

2.7 string类的非成员函数

(1)operator+(string)

返回一个新构造的字符串对象,其值是lhs中的字符与rhs中的字符的连接,即实现字符串加字符串。

此函数被重载成了全局函数,这样就能实现对象加字符串之间的顺序任意性。

(2)operator>>(string)operator<< (string)

istream& operator>> (istream& is, string& str);

重载了>>和<<才能用cin和cout对string类的输入和输出。

(3)relational operators (string)

大小比较:

(4)getline (string)

从输入流的当前位置开始,持续读取字符,直到遇到换行符 \n 为止。

能读取完整的一行文本(包括空格),适合处理带空格的输入(如句子、地址等)。

补充知识:

cin>>读取数据的机制:

当用户从键盘输入数据时,输入的字符会先存入缓冲区,cin>>是从缓冲区读取数据的,而非键盘实时读取,读取过程中会自动先跳过空白字符空格 、制表符 \t、换行符 \n 等),直到遇到非空白字符才开始提取数据,之后遇到空白字符就停止读取。

概括一下流程:

跳过空白字符 → 从缓冲区提取匹配目标类型的字符 → 停止于第一个空白字符 → 残留未处理字符在缓冲区

#include 
#include 
using namespace std;
int main() {int a;double b;string s;// 步骤1:读取整数cout << "请输入一个整数: ";cin >> a;  // 从缓冲区读取整数// 步骤2:读取浮点数cout << "请输入一个浮点数: ";cin >> b;  // 从缓冲区读取浮点数// 步骤3:读取字符串cout << "请输入一个单词: ";cin >> s;  // 从缓冲区读取字符串// 输出读取结果cout << "你输入的整数: " << a << endl;cout << "你输入的浮点数: " << b << endl;cout << "你输入的单词: " << s << endl;return 0;
}

小Tips:

若需读取单个数值不含空格的字符串,用 cin >> 更简洁.

若需读取包含空格的完整行(如用户输入的句子、地址),必须用 getline

例题:

字符串最后一个单词的长度

#include 
using namespace std;
#include
int main() {string str;getline(cin,str);size_t pos=str.rfind(' ');cout<

总结一下:

string最常用的是opereator[]、operator+=、遍历string以及迭代器。


完。

今天的分享就到这里,感谢各位大佬的关注,还请大家多多支持,你们的支持是我前进的最大动力!

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

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

相关文章

【Android之路】界面和状态交互 - 详解

【Android之路】界面和状态交互 - 详解2025-09-28 19:54 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !…

StatusStrip 状态栏控件的使用

作用:用来显示时间 ,状态 ,软件版本 使用:在最下面去点击即可 ,然后再设置 ,鼠标右键置于底层 图片展示:

unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤

unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤​ 本文介绍了如何在 ​CentOS 7​ 系统上手动安装 unzip-6.0-21.el7.x86_64.rpm 这个 RPM 包,包括下载后如何用终端命令进行安装、常见问题的解…

2025过滤器厂家最新推荐TOP5排行榜:覆盖环保过滤器、精密过滤器、高效过滤器,帮企业找到适配优质厂商

当前工业领域中,环保、精密、高效类过滤器已成为流体处理环节的核心设备,直接影响企业生产合规性、产品质量与运营效率。然而,市场上过滤器厂商数量众多,产品质量参差不齐,企业在选型时常常面临技术适配性难判断、…

买域名的网站湖州做网站优化

反物质 反物质是正常物质的反状态。当正反物质相遇时&#xff0c;双方就会相互湮灭抵消&#xff0c;发生爆炸并产生巨大能量。 概念 正电子、负质子都是反粒子&#xff0c;它们跟通常所说的电子、质子相比较&#xff0c;电量相等但电性相反。科学家设想在宇宙中可能存在完全由…

实用指南:零基础学AI大模型之LangChain

实用指南:零基础学AI大模型之LangChainpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

ubi文件系统的 制作 + 挂载

1 ubi文件系统的制作 1.1 测试项目的文件目录结构如下其中diag.img和diag.ubifs是生成的产物。 ubinize.cfg的内容如下[ubifs]mode=ubiimage=diag.ubifsvol_id=0vol_size=9216KiBvol_type=dynamicvol_name=diagvol_ali…

医疗网站是否全部需要前置备案wordpress采集微信公众文章内容

MySQL事务 一、MySQL事物的概念 事务是一种机制&#xff0c;包含了一件事的完整的一个过程 ●事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么…

一款开源免费、组件丰富的 WPF UI 控件库,提供了 100 多款常用控件!

前言 今天大姚给大家分享一款开源免费(MIT License)、组件丰富的 WPF UI 控件库,提供了 100 多款常用控件:CookPopularUI。 项目介绍 CookPopularUI 是一款开源免费(MIT License)、组件丰富的 WPF UI 控件库,提…

元推理用无限嵌套,取代目前弱ai的暴力无限试错

元推理用无限嵌套,取代目前弱ai的暴力无限试错ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891此论断完成了认知范式的终极切割。「元推理用无限嵌套取代暴力无限试错」——这精准定义了ECT-OS-JiuHuaShan框…

小迪安全v2023学习笔记(九十讲)—— 小程序篇反编译外在主包分包调整泄露算法逆向未授权

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

解题报告-序列(alis.*)

序列(alis.*) 题目描述 现在 yxr 给你一个数列,求出此数列的最长递增子序列(不一定连续)的长度。 如果问题就那么简单就好了。哈哈。 现在这个问题还有第 \(2\) 问,设此长度为 \(K\),求此数列可以同时取出多少个长…

PostgreSQL patroni 高可用 4:HAProxy和Keepalived实现读写分离

PostgreSQL patroni 高可用 4:HAProxy和Keepalived实现读写分离PostgreSQL patroni高可用PostgreSQL patroni 高可用 1:ectd 安装和配置PostgreSQL patroni 高可用 2:patroni安装和配置PostgreSQL patroni 高可用 3…

商城网站做推广wordpress woo

这篇文章非常好&#xff0c;必须转载。目录(?)[-] Kernel Space Display架构介绍函数和数据结构介绍函数和数据结构介绍函数和数据结构介绍数据流分析初始化过程分析User Space display接口Kernel display接口典型应用flow分析介绍 Surface manager&#xff08;surface flinge…

c 网站开发数据库连接网站优化推广招聘

原文来源&#xff1a;arXiv作者&#xff1a;Aidin Ferdowsi、 Ursula Challita、Walid Saad、Narayan B. Mandayam「雷克世界」编译&#xff1a;嗯~是阿童木呀、KABUDA对于自动驾驶汽车&#xff08;AV&#xff09;而言&#xff0c;要想在未来的智能交通系统中以真正自主的方式运…

各大网站收录提交入口网站服务器 安全

在 CentOS 7 中设置系统级代理需要几个步骤。以下是设置系统级代理的方法&#xff1a; 设置环境变量: 编辑 /etc/environment 文件&#xff1a; sudo nano /etc/environment添加以下行&#xff08;替换 proxy_server 和 port 为您的实际代理服务器地址和端口&#xff09;&am…

Cloudbox工具箱!一款拥有100款工具的超级工具箱!Cloudbox工具箱教程(附下载)

软件介绍 Cloudbox 工具箱:一款开源免费的 Windows 聚合工具箱,仅 7.6M 大小却集成 198 款工具,涵盖装机检测、系统优化、影音下载等四大类功能,提供绿色免安装软件,能简化装机流程,降低流氓软件捆绑风险。 软件…

java 语法基础课后作业

1:仔细阅读示例: EnumTest.java,运行它,分析运行结果? 你能得到什么结论?你掌握了枚举类型的基本用法了吗?import java.util.*; public enum MyEnum{ ONE, TWO, THREE } class Main{ public static void main(Str…

成都做网站的工资多少如何创立自己的网站

我这个错误是跑完MRP&#xff0c;然后在MD04查看在库/所有量一览&#xff0c; 点计划手配&#xff08;Planned order 计划订单&#xff09;生成 制造指图&#xff08;Production order 生产订单&#xff09;&#xff0c; 到目前这几步都OK&#xff0c;然后在制造指图界面点保…

Lightroom使用教程!一文学会Lightroom使用教程!软件攻略(批量处理)

软件介绍 Lightroom是Adobe Systems开发的一款专业的照片编辑和管理软件,专为摄影师和图像处理专业人士设计。lr修图软件携带的桥正工具,组织功能以及灵活的打印选项,可以帮助用户加快图片后期处理速度,将更多时间…