【C++】- string(!万字讲解C++的string类!!)

string

  • 简单介绍STL
  • string
      • string简介
      • string常用接口
          • 1.string类对象的常见构造
          • 2.string类对象的访问及遍历操作
          • 3.string类对象的修改操作

简单介绍STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

STL为我们提供了许多常用的数据结构和算法,包括数组、链表、栈、队列、堆、集合、映射、排序、查找等等,可以帮助程序员大大提高开发效率。

STL中的容器包括序列式容器和关联式容器两种,序列式容器包括vector、deque、list、forward_list等,而关联式容器则包括set、multiset、map、multimap等。每种容器都有其特定的使用场景和优势,确保了程序员能够轻松地选择合适的容器来处理自己的数据。

在介绍STL中各种常用的容器,我认为容器这个概念可能是从C语言进阶到C++以来的一个陌生的概念:
【C++】- string(!万字讲解C++的string类!!)_第1张图片在C++中,容器通常指一组可存储、访问和管理数据的对象集合。容器可以看作是数据结构的高级形式,可以帮助程序员更方便地组织和操作数据。

不同类型的容器提供了不同的功能和性能特点,以便适应各种应用场景。例如,序列式容器(如vector、deque、list等)提供了线性访问和插入/删除操作,而关联式容器(如set、map等)则提供了基于键值的查找和排序操作。

【C++】- string(!万字讲解C++的string类!!)_第2张图片除了容器,STL中还提供了迭代器、函数对象、算法等其他重要组件。迭代器可以让程序员轻松地遍历容器中的元素,函数对象则可以封装函数并在需要时被调用,而算法则可以对容器中的元素进行各种操作,如查找、排序、去重等等。也就是常说的STL包含六大组件:
【C++】- string(!万字讲解C++的string类!!)_第3张图片
使用STL可以带来很多好处。首先,STL提供了现成的数据结构和算法,这使得程序员不再需要自己实现这些基础组件,节省了大量的时间和精力。这也是它比C语言更简洁的一个原因。其次,STL中的容器和算法都经过了充分测试和优化,因此它们的性能和稳定性都非常可靠。最后,STL的使用可以提高程序的可读性和可维护性,因为它提供了一种标准的、通用的方式来处理各种数据结构和算法。

string

string简介

【C++】- string(!万字讲解C++的string类!!)_第4张图片C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不方便我们直接使用,而在C++中,string是一种表示字符串的类类型。它封装了一系列函数和操作符,使得字符串的操作更加方便和高效,更加方便我们使用
【C++】- string(!万字讲解C++的string类!!)_第5张图片

string常用接口

1.string类对象的常见构造
函数名称 功能
string() 构造空的string类对象,即空字符串
string(const char* s) 用C-string来构造string类对象
string(size_t n, char c) string类对象中包含n个字符c
string(const string&s) 拷贝构造函数

因为这四个函数简单易懂,所以只演示以上四个函数用法:

#include 
#include 

int main() {
    std::string s; // 创建一个空字符串对象
    std::cout << s << std::endl; // 输出空字符串: ""

	string s2("hello bit");//使用一个以 null 结尾的 C 字符串(也称为 C 格式的字符串)来初始化 std::string 类型的对象
	//需要注意的是,如果 C 格式的字符串中包含了空字符(即 \0),则 std::string 对象只会包含空字符之前的部分,后面的内容会被截断。因此,如果要存储包含空字符的字符串,应该使用 std::string 类型的构造函数或者成员函数来处理。


	std::string s(5, 'A'); // 创建一个包含5个重复字符'A'的字符串
    std::cout << s << std::endl; // 输出:AAAAA

	std::string original("Hello");//首先创建了一个原始的字符串对象 original,其值为 "Hello"。然后使用拷贝构造函数 string(const string& s) 创建了一个副本 copy,它与 original 包含相同的内容。最后,通过输出语句分别输出 original 和 copy 的值,可以看到它们的内容是相同的
    std::string copy(original); // 使用拷贝构造函数创建副本
    std::cout << "Original: " << original << std::endl; // 输出:Hello
    std::cout << "Copy: " << copy << std::endl; // 输出:Hello
    return 0;
}
  1. string类对象的容量操作
函数名称 功能
size 返回字符串有效字符长度
lenth 返回字符串有效字符长度
capacity 返回空间总大小
empty 检测字符串释放为空串,是返回true,否则返回false
clear 清空有效字符
reverse 为字符串预留空间
resize 将有效字符的个数该成n个,多出的空间用字符c填充

【C++】- string(!万字讲解C++的string类!!)_第6张图片
示例:

#include 
#include 

int main() {
    std::string s("Hello");
    std::cout << "Length of string: " << s.size() << std::endl; // 输出:Length of string: 5
    return 0;
}

首先创建了一个 std::string 对象 s,其值为 “Hello”。然后通过调用 size() 函数获取了该字符串对象的长度,输出了 5

在string::size()函数中,返回的是size_t类型的无符号整数,来表示字符串对象中字符的数量。由于无符号整数不能为负数,因此使用该函数时需要注意不要与负数进行比较或运算

【C++】- string(!万字讲解C++的string类!!)_第7张图片

在这里插入图片描述

【C++】- string(!万字讲解C++的string类!!)_第8张图片
capacity()函数用于返回字符串对象分配的内存容量。

#include 
#include 

int main() {
    std::string s("Hello");
    std::cout << "Capacity of string: " << s.capacity() << std::endl;
    return 0;
}

在上面的代码中创建了一个 std::string 对象 s,其值为 “Hello”。然后通过调用 capacity() 函数获取了该字符串对象的容量,并输出了结果Capacity of string: 15

在这里插入图片描述需要注意的是,字符串对象的容量可能大于其当前存储的字符数量。这是因为 std::string 类实现时通常会使用一些预留的内存空间,以便在需要时能够快速添加更多的字符,而不必频繁重新分配内存。因此,capacity() 函数返回的值可能大于 size() 或 length() 函数返回的值。

【C++】- string(!万字讲解C++的string类!!)_第9张图片

接下来是判断字符串对象是否为空的函数,

#include 
#include 

int main() {
    std::string s1(""); // 空字符串
    std::string s2("Hello");

    if (s1.empty()) {
        std::cout << "String is empty" << std::endl;
    } else {
        std::cout << "String is not empty" << std::endl;
    }

    if (s2.empty()) {
        std::cout << "String is empty" << std::endl;
    } else {
        std::cout << "String is not empty" << std::endl;
    }

    return 0;
}

在上面的示例中,创建了两个 std::string 对象,分别为 s1 和 s2。s1 是一个空字符串,s2 的值为 “Hello”。通过调用 empty() 函数来判断两个字符串对象是否为空,并输出结果String is empty String is not empty
【C++】- string(!万字讲解C++的string类!!)_第10张图片
clear函数很好理解,这里不做代码演示

在这里插入图片描述
【C++】- string(!万字讲解C++的string类!!)_第11张图片

#include 
#include 

int main() {
    std::string s;

    std::cout << "Before reserve: Capacity is " << s.capacity() << std::endl;

    s.reserve(20);

    std::cout << "After reserve: Capacity is " << s.capacity() << std::endl;

    return 0;
}

在代码演示中,首先创建了一个空的 std::string 对象 s。首先输出了预分配内存前的 capacity() 值,即当前字符串对象的内存容量。然后调用 reserve() 函数,将字符串对象预分配的内存大小设置为 10。最后输出预分配内存后的 capacity() 值

在这里插入图片描述需要注意的是,reserve() 函数只是预分配了内存空间,并不会改变字符串对象中实际存储的字符数量。因此,在使用 reserve() 函数时,应根据预计的字符串长度来选择合适的内存空间大小,以避免过度分配导致的浪费。

此外,reserve() 函数的调用只有在预先知道字符串的最大长度时才有意义,否则可以省略该函数,让 std::string 类根据需要自动管理内存空间
在这里插入图片描述

【C++】- string(!万字讲解C++的string类!!)_第12张图片

#include 
#include 

int main() {
    std::vector<int> numbers = {1, 2, 3};

    std::cout << "Before resize: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    numbers.resize(5, 0);

    std::cout << "After resize: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    numbers.resize(2);

    std::cout << "After resize again: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上面的代码演示中,创建了一个 std::vector 对象 numbers,初始包含了三个整数元素 {1, 2, 3}。首先输出了改变大小前的数组内容,然后调用 resize() 函数将数组大小改为 5,并指定默认值为 0(如果需要扩展数组大小,则使用默认值填充新添加的元素)。接着输出改变大小后的数组内容。最后再次调用 resize() 函数将数组大小改为 2,并输出最终的数组内容。

【C++】- string(!万字讲解C++的string类!!)_第13张图片需要注意的是,当在缩小数组大小时,超出新大小的元素将被删除,而且这些元素的内存空间也会被释放。因此,在进行数组大小缩小操作时,应确保不会丢失需要的数据。另外,如果在扩展数组大小时,指定了默认值,则新添加的元素将使用该默认值填充。

2.string类对象的访问及遍历操作
函数名称 功能
opeator[ ] 返回pos位置的字符,const string类对象调用
begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
范围for C++11支持更简洁的范围for的新遍历方式

【C++】- string(!万字讲解C++的string类!!)_第14张图片
下面是 operator[ ] 的使用示例:

#include 
#include 

int main ()
{
  std::string str ("Test string");
  for (int i=0; i<str.length(); ++i)
  {
    std::cout << str[i];
  }
  return 0;
}

在上面的示例中,我们利用[ ]操作符来输出str的所有位置的字符。
在这里插入图片描述
begin和end是用于返回 std::string 对象的迭代器指向第一个和最后一个字符的函数。它返回的是一个指向字符串中第一个和最后一个字符的迭代器,用法简单,便于理解,这里不作代码演示。而rbegin() 和 rend() 则是两个用于返回 std::string 对象逆序访问的函数。rbegin() 返回一个指向字符串最后一个字符的迭代器,可以用来从后往前遍历整个字符串或部分字符串。rend() 返回一个指向字符串第一个字符前一个位置的迭代器,通常用于表示范围的结束位置
【C++】- string(!万字讲解C++的string类!!)_第15张图片
接下来就是重中之重的范围for
【C++】- string(!万字讲解C++的string类!!)_第16张图片
范围for循环的语法如下:

for (element_declaration : range_expression) {
    // 循环体
}

与常见的for循环不同,element_declaration 是一个新的变量,用于存储每次循环迭代中的元素值。range_expression 是一个表示要遍历的范围的表达式,可以是容器、数组、字符串或其他可迭代对象

代码示例:

#include 
#include 

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用范围for循环遍历容器中的元素
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在示例中,我们定义了一个整数向量 numbers,然后使用范围for循环遍历该向量中的元素。在每次循环迭代中,num 变量被赋值为当前元素的值,然后我们将其打印出来

范围for循环还可以用于遍历其他类型的范围,例如数组、字符串等。无论是容器还是其他可迭代对象,范围for循环都提供了一种简洁和安全的方式来遍历元素。

3.string类对象的修改操作
函数名称 功能
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= 在字符串后追加字符串str
c_str 返回C格式字符串
ind + npos 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回

在这里插入图片描述

【C++】- string(!万字讲解C++的string类!!)_第17张图片
代码演示:

#include 
#include 

int main() {
    std::string str1 = "Hello";
    std::string str2 = " World";

    str1 += str2;   // 等价于 str1 = str1 + str2;

    std::cout << str1 << std::endl;   // 输出 "Hello World"

    return 0;
}

在上述示例中,我们创建了两个 string 对象 str1 和 str2。通过使用 += 操作符,我们将 str2 的内容追加到 str1 的末尾,并将结果重新赋值给 str1。最后,我们输出拼接后的字符串。

【C++】- string(!万字讲解C++的string类!!)_第18张图片并且,operator+= 操作符可以用于字符串与字符串之间的拼接,也可以用于字符串与字符、字符与字符串之间的拼接。

【C++】- string(!万字讲解C++的string类!!)_第19张图片

#include 
#include 

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

    const char* cstr = str.c_str();

    std::cout << cstr << std::endl;  // 输出 "Hello, World!"

    return 0;
}

在用法演示中,我们创建了一个 string 对象 str,其中包含字符串 “Hello, World!”。通过调用 c_str() 函数,我们获得了一个指向以 null 结尾的字符数组的指针 cstr。然后,我们使用 cout 打印出该字符数组的内容。

在这里插入图片描述需要注意的是,c_str() 返回的指针指向的字符数组是 const 类型的,意味着不能通过该指针修改字符串的内容。

以上介绍了string的大致用法,本章就到这里,后续会有新的博客来模拟实现string类,敬请期待。【C++】- string(!万字讲解C++的string类!!)_第20张图片

你可能感兴趣的:(c++,开发语言)