C++ 标准库

40.C++ 标准库——《跟老吕学C++》
C++ 标准库
一、容器
1. 序列容器
1.1 `vector`
1.2 `list`
1.3 `deque`
2. 关联容器
2.1 `set`
2.2 `map`
3. 其他容器
二、迭代器
三、算法
1. 排序算法
2. 查找算法
3. 拷贝和替换算法
4. 自定义算法
四、输入/输出流
1. I/O 流的基本使用
1.1 控制台输入/输出
1.2 文件输入/输出
2. I/O 流的高级功能
2.1 格式化输出
2.2 错误处理
2.3 自定义流类型
五、字符串处理
1. `std::string` 类
2. 字符串查找与替换
3. 字符串分割与连接
4. 字符串与其他数据类型的转换
5. 高级功能:正则表达式匹配和字符串格式化
六、时间日期处理
1. `std::chrono` 库
2. `std::time_t` 类型
3. `std::tm` 结构
4. 时间日期的格式化与解析
5. 高级时间日期计算
总结


C++ 标准库
C++ 标准库是 C++ 编程语言中不可或缺的一部分,它为开发者提供了一系列丰富的功能,帮助开发者更高效地编写出高质量的程序。


C++ 标准库主要可以划分为以下两部分:

1. 标准函数库:这是一个包含了一系列通用的、独立函数的集合,这些函数并不隶属于任何特定的类。该库实质上继承了C语言的标准库,其中包括了如printf、scanf、malloc、free等函数。然而,C++为了提供更高的类型安全性,引入了诸如iostream(替代printf和scanf)以及new和delete(替代malloc和free)等替代品。

标准函数库可以细分为以下几类:

输入/输出(I/O)
字符串和字符处理
数学
时间、日期和本地化
动态内存分配
其他
宽字符函数
以上分类使得标准函数库的内容更加结构化,便于开发者根据自己的需求查找和使用相应的函数。


2. 面向对象类库:这是一个由类和相关函数构成的集合,其主要目标是为开发者提供一系列实用的功能,如容器管理(包括vector、list、map、set等)、迭代器操作、算法实现、字符串处理以及时间日期处理等。具体到标准的C++面向对象类库,它涵盖了输入/输出(I/O)、字符串处理、数值计算等多个方面的支持,详细内容包括:

标准的C++ I/O类:提供数据的输入和输出功能。
String类:支持字符串的创建、编辑和查询操作。
数值类:针对数值数据提供丰富的处理功能。
STL(标准模板库)容器类:包含多种数据容器,如vector、list等。
STL算法:提供了一系列通用的算法操作,如排序、查找等。
STL函数对象:允许开发者在算法中定义自定义操作。
STL迭代器:用于遍历和访问容器中的数据。
STL分配器:管理内存的分配和释放。
本地化库:支持不同地区的本地化设置和格式。
异常处理类:用于处理程序运行时的异常情况。
杂项支持库:包含其他实用的功能和支持工具。
以上分类使得面向对象类库的内容更加条理化,便于开发者根据实际需求快速找到并使用相应的功能。


一、容器
C++ 标准库中的容器类提供了一种高效的方式来存储和管理数据。容器主要分为两大类:序列容器和关联容器。序列容器包括 vector、list、deque、forward_list、array 和 string,而关联容器则涵盖 set、map、multiset 和 multimap。每种容器都有其特定的用途和性能特点,开发者可以根据实际需求选择合适的容器。

这些容器类模板(如 std::vector、std::list、std::deque 等)为开发者提供了多种数据结构的实现,它们不仅简化了数据结构的实现过程,还提供了方便的内存管理和数据操作接口,从而提高了代码的可读性和可维护性。接下来,我们将详细探讨其中一些常用容器的特点和用法。

1. 序列容器
1.1 vector
std::vector 是一个动态数组,可以动态地调整其大小。它支持在尾部进行高效的插入和删除操作,但在中间进行插入或删除操作可能会相对较慢,因为它可能需要移动容器中的其他元素。vector 是最常用的序列容器之一,适用于需要频繁访问和修改元素的场景。

1.2 list
std::list 是一个双向链表,支持在任意位置进行高效的插入和删除操作。与 vector 不同,list 的元素在内存中并不是连续存储的,因此访问特定位置的元素可能相对较慢。然而,list 的优点在于其灵活性和对动态操作的良好支持,适用于需要频繁在列表中插入或删除元素的场景。

1.3 deque
std::deque 是一个双端队列,支持在队列的两端进行高效的插入和删除操作。与 vector 类似,deque 也是一个动态数组,但其内部实现允许在两端进行快速操作。因此,deque 特别适用于需要在队列的两端进行频繁操作的场景。

2. 关联容器
2.1 set
std::set 是一个基于红黑树实现的关联容器,用于存储唯一的元素。它支持快速的查找、插入和删除操作,并自动维护元素的排序。set 特别适用于需要快速判断一个元素是否存在于集合中,或者需要维护一个有序的元素集合的场景。

2.2 map
std::map 是一个关联数组或哈希表,用于存储键值对(key-value pair)。它支持快速的查找、插入和删除操作,并自动维护元素的排序。map 中的元素按照键(key)进行排序,并允许通过键来快速访问对应的值(value)。map 特别适用于需要快速查找、插入和删除键值对的场景。

3. 其他容器
除了上述的序列容器和关联容器外,C++ 标准库还提供了其他一些容器,如 stack、queue、priority_queue 等。这些容器基于其他容器(如 deque)实现,提供了特定的操作接口,以满足特定的需求。例如,stack 提供了后进先出(LIFO)的数据结构实现,queue 提供了先进先出(FIFO)的数据结构实现,而 priority_queue 则是一个基于优先级的队列。

C++ 标准库中的容器类为开发者提供了丰富的数据结构实现和方便的内存管理接口。通过选择合适的容器,开发者可以更加高效、灵活地存储和管理数据,从而提高代码的可读性和可维护性。


二、迭代器
迭代器是C++标准库中的一个核心概念,它提供了一种高效且通用的方式来访问和遍历容器(包括数组)中的元素。迭代器类似于指针,但比指针更加灵活和强大。通过迭代器,我们可以读取、修改容器中的元素,甚至在遍历过程中修改容器本身的结构。

迭代器有多种类型,包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,每种类型的功能和性能各不相同。以下是对这些迭代器类型的简要描述:

输入迭代器:提供对数据的只读访问,并且只能向前移动。例如,输入流迭代器和某些类型的只读容器迭代器。
输出迭代器:只能用于向数据写入,并且只能向前移动。输出流迭代器和某些类型的插入迭代器是输出迭代器的例子。
前向迭代器:可以读取数据,并且可以在容器中向前移动。这种迭代器至少能提供一次性的遍历,但不允许回退。大多数容器(如std::forward_list)都提供前向迭代器。
双向迭代器:除了可以读取数据和向前移动外,还可以向后移动。双向迭代器允许我们在遍历过程中进行一定程度的回退操作,比如std::list和std::set就提供双向迭代器。
随机访问迭代器:这是功能最强大的迭代器类型,它支持所有的迭代器操作,包括读取、写入、向前和向后移动,以及元素之间的算术运算(如加法和减法)。这种迭代器使得我们能够在容器中高效地查找、删除或插入元素。例如,std::vector、std::deque和std::array就提供随机访问迭代器。
C++标准库中的算法通常使用迭代器作为参数,这种设计使得算法与容器之间实现了良好的解耦,从而提高了代码的复用性和灵活性。例如,std::sort算法可以对任何提供随机访问迭代器的容器进行排序,而不需要关心容器的具体类型。

在使用迭代器时,我们需要注意迭代器的有效性和范围。一个有效的迭代器是指它指向一个确实存在的元素或者指向容器的尾后位置(end()函数返回的迭代器)。一个迭代器的范围则是由它的起始迭代器和尾后迭代器定义的。在遍历容器时,我们必须确保迭代器在有效范围内,否则可能会导致未定义的行为。

此外,还需要注意迭代器的失效问题。在某些情况下,如插入或删除容器中的元素时,可能会使某些迭代器失效。失效的迭代器不再指向有效的元素,使用它们可能会导致未定义的行为。因此,在修改容器结构时,我们需要特别小心处理迭代器。

迭代器是C++标准库中一个非常重要的概念,它为我们提供了一种高效且通用的方式来访问和遍历容器中的元素。通过理解和使用迭代器,我们可以编写出更加灵活、高效和可复用的代码。


三、算法
C++标准库中的算法库为开发者提供了一系列通用的算法实现,这些算法能够高效地操作容器中的元素。这些算法包括排序、查找、拷贝、替换(或删除)等,它们的存在极大地提高了编程效率。通过使用这些算法,开发者能够避免编写大量重复的代码,同时确保代码的正确性和可读性。

算法库中的函数通常都接受迭代器作为参数,这使得算法能够与各种容器无缝对接。无论是数组、向量、列表还是其他容器类型,都可以通过迭代器传递给算法函数,从而实现数据的处理。这种灵活性使得算法库能够适用于各种复杂的数据结构和场景。

1. 排序算法
排序算法是算法库中非常重要的一部分。C++标准库提供了多种排序算法的实现,包括std::sort、std::stable_sort、std::partial_sort等。这些算法具有不同的特性,适用于不同的场景。例如,std::sort算法使用了一种高效的排序算法(通常是快速排序或堆排序),能够在平均情况下提供O(n log n)的时间复杂度。而std::stable_sort算法则保证了相等元素的相对顺序不变,这在某些情况下是非常重要的。

2. 查找算法
除了排序算法外,查找算法也是算法库中不可或缺的一部分。C++标准库提供了多种查找算法的实现,如std::find、std::binary_search、std::lower_bound等。这些算法可以在容器中快速定位到指定的元素或满足特定条件的元素。例如,std::find算法使用线性查找的方式在容器中查找指定元素,而std::binary_search算法则要求容器已经排序,并使用二分查找的方式提高查找效率。

3. 拷贝和替换算法
算法库还提供了拷贝和替换算法的实现,如std::copy、std::replace、std::remove等。这些算法可以在容器之间进行数据的拷贝、替换或删除操作。这些算法在处理大数据量时尤为重要,因为它们提供了高效的数据处理方式,避免了手动编写循环代码进行逐个元素的处理。

4. 自定义算法
除了标准库提供的算法外,开发者还可以根据自己的需求自定义算法。C++标准库中的算法通常都接受函数对象或Lambda表达式作为参数,这使得开发者可以定义自己的比较函数或操作函数,并将其传递给算法函数。这种灵活性使得算法库能够适应各种复杂的场景和需求。

C++标准库中的算法库为开发者提供了一系列高效、通用的算法实现,极大地提高了编程效率。通过使用这些算法,开发者可以避免编写大量重复的代码,同时确保代码的正确性和可读性。算法库中的函数通常都接受迭代器作为参数,这使得算法能够与各种容器无缝对接。此外,算法库还提供了一些高级的排序算法和查找算法,这些算法在特定场景下能够展现出更优异的性能表现。因此,熟练掌握C++标准库中的算法库对于提高编程能力和代码质量具有重要意义。


四、输入/输出流
C++ 标准库中的 I/O 流库为处理输入和输出提供了一种类型安全且易于使用的方式。这个库包含了一系列类,如 ifstream、ofstream、fstream,以及标准输入输出流 std::cin 和 std::cout,这些类被用于文件、控制台和其他 I/O 设备。通过使用这些类,开发者可以轻松地进行文件读写、控制台输入输出等操作。

具体而言,C++ 标准库中的输入/输出流库提供了一套完整的 I/O 操作接口,用于从输入设备读取数据和向输出设备写入数据。这些类(如 std::cin、std::cout、std::ifstream、std::ofstream)封装了底层 I/O 操作的细节,使得开发者无需关心底层实现的复杂性,就能方便地进行文件读写、控制台输入输出等操作。此外,流库还支持自定义流类型,进一步扩展了 I/O 操作的功能。

1. I/O 流的基本使用
1.1 控制台输入/输出
控制台输入/输出通常使用 std::cin 和 std::cout。std::cin 用于从标准输入(通常是键盘)读取数据,而 std::cout 用于向标准输出(通常是屏幕)写入数据。

#include <iostream>

int main() {
    int x;
    std::cout << "请输入一个整数: ";
    std::cin >> x;
    std::cout << "你输入的整数是: " << x << std::endl;
    return 0;
}
1
2
3
4
5
6
7
8
9
1.2 文件输入/输出
文件输入/输出则使用 std::ifstream(用于读取文件)和 std::ofstream(用于写入文件)。这些类允许开发者以文件为单位进行数据的读写操作。

#include <fstream>
#include <iostream>

int main() {
    std::ofstream outputFile("output.txt");
    if (outputFile.is_open()) {
        outputFile << "这是写入到文件的内容。\n";
        outputFile.close();
    } else {
        std::cout << "无法打开文件进行写入!" << std::endl;
    }

    std::ifstream inputFile("output.txt");
    if (inputFile.is_open()) {
        std::string line;
        while (std::getline(inputFile, line)) {
            std::cout << line << std::endl;
        }
        inputFile.close();
    } else {
        std::cout << "无法打开文件进行读取!" << std::endl;
    }

    return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2. I/O 流的高级功能
2.1 格式化输出
std::cout 允许使用格式化标志和操纵符来控制输出的格式,如设置精度、填充字符、对齐方式等。

#include <iostream>
#include <iomanip>

int main() {
    double pi = 3.14159265358979323846;
    std::cout << std::fixed << std::setprecision(2) << pi << std::endl;  // 输出固定小数点后两位
    return 0;
}
1
2
3
4
5
6
7
8
2.2 错误处理
I/O 流库提供了错误处理机制,允许开发者检查流的状态(如是否成功打开文件、是否遇到文件结束符等),并在需要时抛出异常。

#include <fstream>
#include <iostream>

int main() {
    std::ifstream inputFile("nonexistent.txt");
    if (!inputFile) {
        std::cerr << "无法打开文件!\n";
        return 1;
    }
    // 其他代码...
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
2.3 自定义流类型
虽然 C++ 标准库已经提供了丰富的流类型,但开发者仍然可以通过继承 std::basic_streambuf 或其派生类(如 std::filebuf、std::stringbuf 等)来创建自定义的流类型,以满足特定的 I/O 需求。

C++ 标准库中的 I/O 流库为开发者提供了一种强大且灵活的 I/O 操作方式,使得文件读写、控制台输入输出等操作变得简单而高效。


五、字符串处理
C++标准库中的字符串处理库为开发者提供了一系列函数和类,用于高效地处理字符串数据。这些工具涵盖了字符串的查找、替换、分割、连接等基本操作,以及与其他数据类型的转换。特别地,std::string 类封装了字符串的底层实现细节,使得开发者能够更加方便地进行各种字符串操作。此外,字符串处理库还支持高级功能,如正则表达式匹配和字符串格式化,以满足更为复杂的需求。

1. std::string 类
std::string 是C++标准库中用于处理字符串的类。它提供了丰富的成员函数和操作符重载,使得字符串的操作变得简单直观。例如,可以使用 + 操作符连接两个字符串,使用 = 操作符赋值,使用 append() 方法在字符串末尾添加内容,使用 substr() 方法提取子串等。

2. 字符串查找与替换
C++标准库提供了多种字符串查找和替换的方法。例如,std::string 类中的 find() 和 find_first_of() 方法可以用于在字符串中查找子串或字符,而 replace() 方法则可以实现字符串的替换操作。这些方法在处理文本数据时非常有用,如解析配置文件、处理用户输入等。

3. 字符串分割与连接
字符串的分割和连接是常见的字符串操作。C++标准库中的 std::getline() 函数可以用于从输入流中读取一行文本,并将其分割为多个字符串。而 std::stringstream 类则提供了一种更为灵活的方式来处理字符串的分割和连接。通过将字符串插入到 std::stringstream 对象中,可以使用流操作符 >> 和 << 来实现字符串的分割和连接。

4. 字符串与其他数据类型的转换
C++标准库提供了多种将字符串与其他数据类型进行转换的方法。例如,std::stoi()、std::stol() 和 std::stod() 等函数可以将字符串转换为整数、长整数和双精度浮点数。同样地,std::to_string() 函数可以将整数、浮点数等数据类型转换为字符串。这些转换函数在处理用户输入、生成输出等场景中非常有用。

5. 高级功能:正则表达式匹配和字符串格式化
除了基本的字符串操作外,C++标准库还支持更高级的功能,如正则表达式匹配和字符串格式化。正则表达式是一种强大的文本处理工具,可以用于匹配、查找和替换符合特定模式的文本。C++标准库中的 <regex> 头文件提供了正则表达式相关的类和函数。而字符串格式化则可以使用 std::format() 函数(C++20及以后版本)来实现,该函数提供了一种灵活且易于使用的方式来生成格式化的字符串。

C++标准库中的字符串处理库为开发者提供了一系列强大而灵活的工具,用于处理字符串数据。通过熟练掌握这些工具的使用方法,开发者可以更加高效地进行文本处理、解析配置文件、处理用户输入等操作。


六、时间日期处理
C++ 标准库中的时间日期处理库为开发者提供了一套功能强大的函数和类,用于处理时间和日期相关的任务。这些工具包括获取当前时间、格式化时间日期、解析时间日期字符串等。通过使用这些函数和类,开发者能够轻松地在程序中处理时间和日期数据。

具体来说,C++ 标准库中的时间日期处理库包含了如 std::chrono、std::time_t、std::tm 等类,它们封装了时间和日期的底层实现细节,从而简化了开发者的使用。

1. std::chrono 库
std::chrono 库是 C++11 引入的,它提供了一组类型、函数和算法,用于处理时间间隔和时钟。这个库中的 std::chrono::system_clock、std::chrono::steady_clock 和 std::chrono::high_resolution_clock 等类型可以帮助开发者获取当前的系统时间或稳定的时钟时间。同时,std::chrono::duration 类型可以表示时间间隔,并提供了一系列的操作符和函数来执行时间运算。

2. std::time_t 类型
std::time_t 是一个简单的算术类型,通常用于表示从某个固定时间点(如 Unix 纪元,即 1970 年 1 月 1 日 00:00:00 UTC)以来的秒数。它可以通过 std::time 函数获取当前时间,并可以将它转换为 std::tm 结构进行进一步处理。

3. std::tm 结构
std::tm 是一个结构体,用于表示分解后的时间(年、月、日、小时、分钟、秒等)。它可以通过 std::localtime 或 std::gmtime 函数将 std::time_t 转换为本地时间或协调世界时(UTC)。此外,还可以使用 std::strftime 函数将 std::tm 结构格式化为字符串。

4. 时间日期的格式化与解析
除了获取和分解时间日期之外,C++ 标准库还提供了函数来格式化和解析时间日期字符串。std::strftime 函数可以将 std::tm 结构格式化为符合指定格式的字符串,而 std::strptime 函数(虽然它不是 C++ 标准库的一部分,但在许多平台上都可用)可以将字符串解析为 std::tm 结构。

5. 高级时间日期计算
对于更高级的时间日期计算任务,如时区转换和闰年判断等,C++ 标准库本身并没有提供直接的支持。但是,开发者可以使用第三方库(如 Boost.DateTime 或 ICU)来执行这些任务。这些库提供了更丰富的功能和更灵活的接口,可以满足更复杂的时间日期处理需求。

C++ 标准库中的时间日期处理库为开发者提供了一套强大的工具来处理时间和日期相关的任务。通过使用这些函数和类,开发者可以轻松地获取当前时间、格式化时间日期、解析时间日期字符串,并执行更复杂的时间日期计算任务。


总结
C++ 标准库为开发者提供了丰富的功能和工具,可以大大提高开发者的编程效率和质量。通过学习和掌握 C++ 标准库中的各个组件和概念,开发者可以更加高效和灵活地编写出高质量的 C++ 程序。C++ 标准库为开发者提供了丰富的功能和强大的支持,使得开发者能够更加高效地编写高质量的程序。掌握 C++ 标准库的使用是成为一名优秀的 C++ 程序员的重要前提。


————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/molangmolang/article/details/140306125

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值