C++ 标准库和标准模板库

news2025/1/21 12:22:14

参考:

C++ STL 教程 | 菜鸟教程 (runoob.com)

C++标准库和标准模板库 - 星朝 - 博客园 (cnblogs.com)

C++强大的功能来源于其丰富的类库及库函数资源。C++标准库的内容总共在50个标准头文件中定义。在C++开发中,要尽可能地利用标准库完成。这样做的直接好处包括:

(1)成本:已经作为标准提供,何苦再花费时间、人力重新开发呢;

(2)质量:标准库的都是经过严格测试的,正确性有保证;

(3)效率:关于人的效率已经体现在成本中了,关于代码的执行效率要相信实现标准库的大牛们的水平;

(4)良好的编程风格:采用行业中普遍的做法进行开发。

在掌握了基本原理的基础上,在认识标准库的问题上完全可以凭借实践,逐步地掌握。标准库的学习不需要认认真真地读书,需要的是在了解概貌的情况下,在实践中深入。

C++标准库

注意,c++标准库并非是glibc,别搞错了。

C++ 标准库包括一组头文件,这些头文件提供了各种功能和工具,涵盖了输入输出、容器、算法、多线程、正则表达式等。

C++ 标准库可以分为两部分:

  • 标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言,继承自c语言,但并非和c语言一致。

  • 面向对象类库: 这个库是类及其相关函数的集合。

C++ 标准库包含了所有的 C 标准库,为了支持类型安全,做了一定的添加和修改。

以下是 C++ 标准库的主要组件分类及对应的头文件列表:

输入输出

  • <iostream>: 标准输入输出流

  • <fstream>: 文件输入输出流

  • <sstream>: 字符串流

  • <iomanip>: 输入输出流格式化

容器

  • <array>: 定长数组容器

  • <vector>: 动态数组容器

  • <deque>: 双端队列容器

  • <list>: 双向链表容器

  • <forward_list>: 单向链表容器

  • <stack>: 栈容器适配器

  • <queue>: 队列容器适配器

  • <priority_queue>: 优先队列容器适配器

  • <set>: 集合容器(基于平衡二叉树)

  • <unordered_set>: 无序集合容器(基于哈希表)

  • <map>: 映射容器(键值对,基于平衡二叉树)

  • <unordered_map>: 无序映射容器(基于哈希表)

  • <bitset>: 二进制位容器

算法和迭代器

  • <algorithm>: 常用算法(如排序、查找等)

  • <iterator>: 迭代器

函数对象和绑定

  • <functional>: 定义函数对象及相关工具

数学和数值运算

  • <numeric>: 数值操作(如累计、乘积等)

  • <complex>: 复数运算

  • <valarray>: 数组类及相关操作

  • <cmath>: 数学函数

字符串和正则表达式

  • <string>: 标准字符串类

  • <regex>: 正则表达式

时间和日期

  • <ctime>: 时间处理

  • <chrono>: 时间库

多线程和并发

  • <thread>: 多线程支持

  • <mutex>: 互斥量

  • <condition_variable>: 条件变量

  • <future>: 异步编程支持

  • <atomic>: 原子操作

内存管理

  • <memory>: 智能指针及动态内存管理

  • <new>: 动态内存分配

类型特性和运行时类型识别

  • <type_traits>: 类型特性

  • <typeinfo>: 运行时类型识别

异常处理

  • <exception>: 异常处理基类及相关工具

  • <stdexcept>: 常用异常类(如 std::runtime_error 等)

输入输出操作

  • <cstdio>: C 风格输入输出

  • <cstdint>: 定长整数类型

其他工具

  • <utility>: 通用工具(如 std::pair 和 std::move 等)

  • <random>: 随机数生成

  • <locale>: 本地化支持

  • <codecvt>: 字符编码转换

  • <cassert>: 断言

  • <cctype>: 字符处理

  • <cstring>: 字符串处理

  • <cwchar>: 宽字符处理

  • <climits>: 数值极限

  • <cfloat>: 浮点极限

  • <cstdlib>: 常用工具(如 std::randstd::abs 等)

这些头文件构成了C++标准库的基础,提供了丰富的功能,支持开发者进行各种类型的编程任务。

注意,这些头文件都不是.h头文件,而是一个一个的类。

标准模板库STL

STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

C++ 标准模板库(Standard Template Library,STL)是一套功能强大的 C++ 模板类和函数的集合,它提供了一系列通用的、可复用的算法和数据结构。

STL 分为多个组件,包括容器(Containers)、迭代器(Iterators)、算法(Algorithms)、函数对象(Function Objects)和适配器(Adapters)等。

使用 STL 的好处:

  • 代码复用:STL 提供了大量的通用数据结构和算法,可以减少重复编写代码的工作。

  • 性能优化:STL 中的算法和数据结构都经过了优化,以提供最佳的性能。

  • 泛型编程:使用模板,STL 支持泛型编程,使得算法和数据结构可以适用于任何数据类型。

  • 易于维护:STL 的设计使得代码更加模块化,易于阅读和维护。

C++ 标准模板库的核心包括以下重要组件组件:

这些个组件都带有丰富的预定义函数,帮助我们通过简单的方式处理复杂的任务。

对于STL的使用,也普遍存在着两种观点。第一种认为STL的最大作用在于充当经典的数据结构和算法教材,因为它的源代码涉及了许多具体实现方面的问题。第二种则认为STL的初衷乃是为了简化设计,避免重复劳动,提高编程效率,因此应该是“应用至上”的,对于源代码则不必深究。对于初学者而言,通过分析源代码,提高对其应用的理解其意义也不同凡响。

不少C++的经典教材对STL都有非常好的讲解,可以选一本去读。在读书时,要开始学着挑着读,跳着读,不必从头到尾,逐页去读。在这个阶段,可以首先学习迭代器utility、在C++编程中建议替代数组的vector,以及实现双向链表的list。等等。

这里简单介绍一些常用的模板库。

容器

容器其实就是一些数据结构的实现。

关于容器部分,可参考:

C++ 容器类 <vector> | 菜鸟教程 (runoob.com)史上最全的各种C++ STL容器全解析 - Seaway-Fu - 博客园 (cnblogs.com)

vector 容器

参考:C++ 容器类 <vector> | 菜鸟教程 (runoob.com)

C++ 中的 vector 是一种序列容器,它允许你在运行时动态地插入和删除元素。

可以看做一个动态数组。

vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。

与 C++ 数组相比,vector 具有更多的灵活性和功能,使其成为 C++ 中常用的数据结构之一。

vector 是 C++ 标准模板库(STL)的一部分,提供了灵活的接口和高效的操作。

基本特性:

  • 动态大小vector 的大小可以根据需要自动增长和缩小。

  • 连续存储vector 中的元素在内存中是连续存储的,这使得访问元素非常快速。

  • 可迭代vector 可以被迭代,你可以使用循环(如 for 循环)来访问它的元素。

  • 元素类型vector 可以存储任何类型的元素,包括内置类型、对象、指针等。

使用场景:

  • 当你需要一个可以动态增长和缩小的数组时(类型仍然需要保持一致)。

  • 当你需要频繁地在序列的末尾添加或移除元素时。

  • 当你需要一个可以高效随机访问元素的容器时。

在 C++ 中,使用 <vector> 需要包含头文件 <<vector>>。以下是一些基本的语法:

  • 声明一个 vector

    std::vector<int> myVector;//注意,int是该容器的类型,放在vector类后面的尖括号<>里
  • 添加元素:

    myVector.push_back(10);
  • 访问元素:

    int firstElement = myVector[0];
  • 获取元素数量:

    size_t size = myVector.size();
  • 清空 vector

    myVector.clear();
    

下面是一个使用 <vector> 的简单示例,包括输出结果。

#include <iostream>
#include <vector>

int main() {
    // 声明一个存储整数的 vector
    std::vector<int> numbers;

    // 添加元素
    numbers.push_back(10);
    numbers.push_back(20);
    numbers.push_back(30);

    // 输出 vector 中的元素
    std::cout << "Vector contains: ";
    for (int i = 0; i < numbers.size(); ++i) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // 添加更多元素
    numbers.push_back(40);
    numbers.push_back(50);

    // 再次输出 vector 中的元素
    std::cout << "After adding more elements, vector contains: ";
    for (int i = 0; i < numbers.size(); ++i) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // 访问特定元素
    std::cout << "The first element is: " << numbers[0] << std::endl;

    // 清空 vector
    numbers.clear();

    // 检查 vector 是否为空
    if (numbers.empty()) {
        std::cout << "The vector is now empty." << std::endl;
    }

    return 0;
}

输出结果:

Vector contains: 10 20 30 
After adding more elements, vector contains: 10 20 30 40 50 
The first element is: 10 
The vector is now empty.

<vector> 是 C++ STL 中一个非常有用的容器,它提供了动态数组的功能,使得元素的添加和删除变得更加灵活和方便。通过上述示例,初学者可以快速了解 <vector> 的基本用法和操作。随着学习的深入,你将发现 <vector> 在实际编程中的强大功能和广泛应用。

map 容器

参考:C++ 容器类 <map> | 菜鸟教程 (runoob.com)

在 C++ 中,<map> 是标准模板库(STL)的一部分,它提供了一种关联容器,用于存储键值对(key-value pairs)。

map 容器中的元素是按照键的顺序自动排序的,这使得它非常适合需要快速查找和有序数据的场景。

定义和特性

  • 键值对map 存储的是键值对,其中每个键都是唯一的。

  • 排序map 中的元素按照键的顺序自动排序,通常是升序。

  • 唯一性:每个键在 map 中只能出现一次。

  • 双向迭代器map 提供了双向迭代器,可以向前和向后遍历元素。

包含头文件:

#include <map>

声明 map 容器:

std::map<key_type, value_type> myMap;
  • key_type 是键的类型。
  • value_type 是值的类型。

插入元素:

myMap[key] = value;

访问元素:

value = myMap[key];

遍历 map:

for (std::map<key_type, value_type>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
    std::cout << it->first << " => " << it->second << std::endl;
}

下面是一个使用 map 的简单实例,我们将创建一个 map 来存储员工的姓名和他们的年龄,并遍历这个 map 来打印每个员工的姓名和年龄。

#include <iostream>#include <map>
#include <string>

int main() {
    // 创建一个 map 容器,存储员工的姓名和年龄
    std::map<std::string, int> employees;

    // 插入员工信息
    employees["Alice"] = 30;
    employees["Bob"] = 25;
    employees["Charlie"] = 35;

    // 遍历 map 并打印员工信息
    for (std::map<std::string, int>::iterator it = employees.begin(); it != employees.end(); ++it) {
        std::cout << it->first << " is " << it->second << " years old." << std::endl;
    }

    return 0;
}

输出结果:

Alice is 30 years old.
Bob is 25 years old.
Charlie is 35 years old.

map 是 C++ STL 中一个非常有用的容器,特别适合需要快速查找和有序数据的场景。 

迭代器

参考:

C++ 标准库 <iterator> | 菜鸟教程 (runoob.com)

C++ 标准库中的 <iterator> 头文件提供了一组工具,用于遍历容器中的元素。迭代器是 C++ 标准模板库(STL)中的核心概念之一,它允许程序员以统一的方式访问容器中的元素,而不需要关心容器的具体实现细节。

迭代器是一个对象,它提供了一种方法来遍历容器中的元素。迭代器可以被视为指向容器中元素的指针,但它比指针更加灵活和强大。迭代器可以用于访问、修改容器中的元素,并且可以与 STL 算法一起使用。

迭代器主要分为以下几类:

  1. 输入迭代器(Input Iterator):只能进行单次读取操作,不能进行写入操作。
  2. 输出迭代器(Output Iterator):只能进行单次写入操作,不能进行读取操作。
  3. 正向迭代器(Forward Iterator):可以进行读取和写入操作,并且可以向前移动。
  4. 双向迭代器(Bidirectional Iterator):除了可以进行正向迭代器的所有操作外,还可以向后移动。
  5. 随机访问迭代器(Random Access Iterator):除了可以进行双向迭代器的所有操作外,还可以进行随机访问,例如通过下标访问元素。

迭代器的语法通常如下:

#include <iterator>

// 使用迭代器遍历容器
for (ContainerType::iterator it = container.begin(); it != container.end(); ++it) {
    // 访问元素 *it
}

下面是一个使用 <iterator> 头文件和迭代器遍历 std::vector 的示例:

#include <iostream>
#include <vector>
#include <iterator>

int main() {
    // 创建一个 vector 容器并初始化
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用迭代器遍历 vector
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 使用 auto 关键字简化迭代器类型
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 使用 C++11 范围 for 循环
    for (int elem : vec) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果:

1 2 3 4 5 
1 2 3 4 5 
1 2 3 4 5 

通过使用 <iterator> 头文件,我们可以方便地遍历 C++ STL 容器中的元素。迭代器提供了一种统一的接口,使得我们可以在不同的容器之间切换,而不需要改变遍历的代码。这大大提高了代码的可重用性和可维护性。

对于初学者来说,理解迭代器的概念和使用方式是非常重要的,因为它们是 C++ STL 的基础。希望这篇文章能帮助你更好地理解迭代器,并在你的 C++ 编程中有效地使用它们。

内存管理库 <memory>

参考:C++ 内存管理库 <memory> | 菜鸟教程 (runoob.com)

<memory> 是 C++ 标准库中的一个头文件,它包含了用于动态内存管理的模板和函数。

在 C++ 中,内存管理是一个重要的概念。动态内存管理允许程序在运行时分配和释放内存,这在处理不确定大小的数据结构时非常有用。然而,不正确的内存管理可能导致内存泄漏、野指针等问题。

<memory> 头文件提供了智能指针等工具,帮助开发者更安全地管理动态内存。

智能指针

智能指针是 <memory> 头文件中的核心内容。它们是 C++11 引入的特性,用于自动管理动态分配的内存。智能指针的主要类型有:

  • std::unique_ptr:独占所有权的智能指针,同一时间只能有一个 unique_ptr 指向特定内存。

  • std::shared_ptr:共享所有权的智能指针,多个 shared_ptr 可以指向同一内存,内存在最后一个 shared_ptr 被销毁时释放。

  • std::weak_ptr:弱引用智能指针,用于与 shared_ptr 配合使用,避免循环引用导致的内存泄漏。

举例:使用 std::unique_ptr

#include <iostream>
#include <memory>

class MyClass {
public:
    void doSomething() {
        std::cout << "Doing something" << std::endl;
    }
};

int main() {
    std::shared_ptr<MyClass> myPtr1(new MyClass());
    std::shared_ptr<MyClass> myPtr2 = myPtr1;

    myPtr1->doSomething(); // 使用 myPtr1 调用成员函数
    myPtr2->doSomething(); // 使用 myPtr2 调用成员函数

    // 当 myPtr1 和 myPtr2 都被销毁时,MyClass 对象的内存才会被释放
    return 0;
}

输出结果:

Doing something
Doing something

其实,就是用来定义一个指针的类型,比如:

std::shared_ptr<MyClass> myPtr2 = myPtr1;

就是定一个指针对象myPtr2,该指针的指针类型是shared_ptr<MyClass>,shared_ptr<MyClass>表示shared_ptr类型是指向MyClass类型。

C++中,用各种类来定义对象,如果有类型,那么类型就需要放在类后面的尖括号<>中。

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

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

相关文章

【Jenkins未授权访问漏洞 】

默认情况下 Jenkins面板中用户可以选择执行脚本界面来操作一些系统层命令&#xff0c;攻击者可通过未授权访问漏洞或者暴力破解用户密码等进入后台管理服务&#xff0c;通过脚本执行界面从而获取服务器权限。 第一步&#xff1a;使用fofa语句搜索 搜索语句&#xff1a; port&…

NICE Seminar(2022-7-17)进化约束优化(中南大学王勇教授)

​​​​​​​ ACO偏向于离散 DE和PSO偏向于连续变量 确定性替换和随机替换 存在缺陷&#xff0c;可行域可能有多个。 Pfea为可行解所占比例 目标空间中的可行域与在决策空间的可行域中的对应关系&#xff1f;&#xff1f;&#xff1f; 维度中套维度&#xff1f;&#xff1…

苹果 Safari 的隐私保护与广告追踪问题 :技术进展与挑战

隐私保护的进展与挑战 近年来&#xff0c;浏览器行业在隐私保护技术方面取得了显著进展&#xff0c;尤其是在广告追踪领域。谷歌的 Chrome 浏览器推广了隐私沙盒&#xff0c;通过将用户可能感兴趣的主题分类并推送给广告商。Mozilla Firefox 和 Meta Facebook 则推出了一种名为…

C 语言学习(5) ---- 汇编语法基础

目录 汇编语言基础x86 体系的寄存器说明Intel 和 AT&T 语法"helloworld" 汇编程序分析指令和伪指令TBD 汇编语言基础 汇编程序基本由 4 种类型的组件组成&#xff1a;指令&#xff08;instruction&#xff09;、伪指令&#xff08;directive&#xff09;、标号&…

Python在指定文件夹下创建虚拟环境

基于不同python版本和第三方包版本开发的项目&#xff0c;为了方便学习和管理python环境&#xff0c;可以在指定的文件夹里创建项目所需的虚拟环境。具体流程如下&#xff1a; (1) 以管理员身份打开Ananconda Prompt&#xff0c;查看当前虚拟环境&#xff0c;输入命令如下&…

C#中的Modbus协议

协议介绍 关于Modbus协议&#xff1a; Modbus协议是MODICON&#xff08;莫迪康&#xff09;&#xff08;现施耐德品牌&#xff09;在1979年开发的&#xff0c;是全球第一个真正用于现场的总线协议&#xff1b;Modbus协议是应用于电子控制器上的一种通用语言。通过此协议&…

一、报名与安装软件

声明 首先声明这个考试是需要费用的&#xff0c;目前我缴纳的费用是980元 官网 报名与学习官网为&#xff1a;https://cloud.aigccert.com/web/index 选择此处&#xff0c;点击报名后按要求完善个人信息。 完善个人信息后可以开始学习视频&#xff0c;视频内容看起来多其实…

Servlet开发流程 (里面有Idea项目添加Tomcat依赖详细教程)

目标: 校验注册时&#xff0c;用户名是否被占用。通过客户端向一个Servlet发送请求&#xff0c;携带username&#xff0c;如果用户 名是zhangsan&#xff0c;则向客户端响应 NO&#xff0c;如果是其他&#xff0c;响应YES。 1.在idea中创建web工程 1右键点击父工程-New-Module …

【MySQL 01】在 Ubuntu 22.04 环境下安装 MySQL

文章目录 &#x1f308; 1. 说明&#x1f308; 2. 卸载不必要的环境&#x1f308; 3. 安装 MySQL&#x1f308; 4. 启动和关闭 MySQL 服务&#x1f308; 5. 临时登录 MySQL&#x1f308; 6. 设置 MySQL 密码&#x1f308; 7. 配置 MySQL &#x1f308; 1. 说明 在安装与卸载中…

此卷不包含可识别的文件系统‘及高效数据恢复策略

在数字信息的海洋中遨游时&#xff0c;我们偶尔会遭遇“此卷不包含可识别的文件系统”这一突如其来的警示&#xff0c;它像是一道无形的屏障&#xff0c;阻挡了我们与宝贵数据之间的直接联系。这一错误提示&#xff0c;往往意味着存储设备的文件系统结构出现了异常&#xff0c;…

嵌入式全栈开发学习笔记---数据结构概述

目录 入门级概念 什么是数据结构&#xff1f; 什么是算法&#xff1f;算法和数据结构有什么联系&#xff1f; 为什么要学习数据结构&#xff1f; 逻辑结构 线性结构&#xff08;嵌入式领域的重点&#xff09; 树形结构 图形结构 线性结构&#xff08;嵌入式领域的重点…

【书生大模型实战营(暑假场)】入门任务二 Git 关卡

入门任务二 Git 关卡 参考&#xff1a; 教程任务 1 闯关任务 1.1 使用 Git 完成破冰介绍 本任务将基于开发机实现&#xff0c;重点在于熟悉Git操作。首先要了解 Git操作的常见四部曲&#xff0c;即&#xff1a;舔 Add&#xff0c;提 Commit&#xff0c;拉 Pull&#xff0c…

架构师知识梳理(一):计算机硬件

目录 计算机硬件组成 CPU CPU的组成 CPU的功能 校验码 奇偶校验 CRC CRC计算案例 指令 指令指行过程 指令系统 指令系统分类 指令流水线技术 流水线技术相关计算公式 存储 计算机存储系统设计 高速缓存Cache 缓存的局部性原理 地址映射 替换算法 关于命中…

2024华数杯数学建模竞赛选题建议+初步分析

提示&#xff1a;DS C君认为的难度&#xff1a;C<A<B&#xff0c;开放度&#xff1a;A<B<C。 综合评价来看 A题适合对机械臂和机器人运动学感兴趣的同学&#xff0c;尤其是有一定编程和优化算法基础的同学。不建议非相关专业同学选择。 B题挑战较大&#xff0…

红黑树的概念及应用

参考文章&#xff1a;红黑树c实现 一.红黑树是什么 红黑树是一种自平衡二叉查找树&#xff0c;是计算机科学领域中的一种数据结构&#xff0c;典型的用途是实现关联数组&#xff0c;存储有序的数据。它可以在O(logn)时间内做查找&#xff0c;插入和删除&#xff0c;这里的n是树…

Docker Remote API 未授权访问漏洞

Docker Remote API 未授权访问漏洞 Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的LINUX机器上&#xff0c;也可以实现虚拟化。 Docker swarm 是一个将docker集群变成单一虚拟的docker…

LeetCode刷题笔记 | 643 | 子数组最大平均数 | 双指针 | 滑动窗口 | 数组 | Java | 详细注释 | 三种解法

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 双指针在一定条件下可以转化成滑动窗口&#xff0c;这道题就是个很好的例子 LeetCode链接&#xff1a;643. 子数组最大平均数 I 1.题目描述 给你一个由 n 个元素组成…

SpringMVC 工作流程简述

SpringMVC 工作流程简述 1. 请求接收2. 请求解析3. 查找处理器4. 处理器适配5. 调用处理器6. 处理结果7. 结果传递8. 视图解析9. 视图渲染10. 响应用户 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; #mermaid-svg-xZqkXNPjG0SH5tMA {font-…

经典算法KMP讲解,包含C++解法ACM模式

写在前面&#xff1a;一个人能走的多远不在于他在顺境时能走的多快&#xff0c;而在于他在逆境时多久能找到曾经的自己。——KMP 讲解前置知识模拟next的构建匹配思路匹配字符串构建next数组 模板代码 题目一&#xff1a;KMP字符串题目二&#xff1a;找出字符串中第一个匹配项的…

电脑开机启动项管理小工具,绿色免安装

HiBit Startup Manager 是一款功能强大的启动项管理工具&#xff0c;旨在帮助用户管理和优化计算机的自动启动程序。该软件通过添加或删除应用程序、编辑它们的属性以及管理流程、服务、任务调度程序和上下文菜单来实现这一目标。 HiBit Startup Manager 提供了以下主要功能&a…