【C++】——【 STL简介】——【详细讲解】

news2024/12/28 17:58:27

目录

​编辑

1. 什么是STL

2. STL的版本

3. STL的六大组件

1.容器(Container):

2.算法(Algorithm):

3.迭代器(Iterator):

4.函数(Function):

5.适配器(Adapter):

6.分配器(Allocator):

4. STL的重要性

5. 如何学习STL

6. STL的缺陷

总结


专栏:C++学习笔记 

1. 什么是STL

STL(Standard Template Library,标准模板库)是C++标准库的重要组成部分。它不仅是一个可复用的组件库,而且是一个包含数据结构与算法的软件框架。STL为开发者提供了多种高效、灵活且可扩展的模板化工具,使得复杂的程序开发变得更加简单和高效。

代码示例:使用STL的vector容器

#include <iostream>
#include <vector>

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

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

    return 0;
}

运行结果

小李很执着理解

  • vector就像一个可以自动扩展的数组,你可以随意添加或删除元素。
  • 在上面的例子中,创建了一个包含数字1到5的vector,并输出这些数字。

2. STL的版本

STL经历了多个版本的发展,不同版本有不同的特点和应用场景:

  • 原始版本:由Alexander Stepanov和Meng Lee在惠普实验室完成的原始版本。这个版本是开源的,允许任何人任意使用、修改和传播。
  • P. J. 版本:由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用。这一版本不能公开或修改,其缺陷在于可读性较低,符号命名比较怪异。
  • RW版本:由Rouge Wage公司开发,继承自HP版本,被C++ Builder采用,也不能公开或修改,但可读性一般。
  • SGI版本:由Silicon Graphics Computer Systems公司开发,继承自HP版本,被GCC(Linux)采用。这个版本可移植性好,可公开、修改甚至商业使用。从命名风格和编程风格上看,阅读性非常高。

小李很执着理解

  • 不同版本的STL是由不同的人和公司开发的,有些版本是开源的,有些版本是商业化的。
  • 学习STL时主要参考SGI版本,因为它的可读性和移植性都很好。

3. STL的六大组件

STL由以下六大组件组成:

1.容器(Container)

用于存储和组织数据的对象,如vectorlistdequesetmap等。

代码示例:使用map容器

#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> age;
    age["Alice"] = 30;
    age["Bob"] = 25;

    for (const auto& pair : age) {
        std::cout << pair.first << " is " << pair.second << " years old." << std::endl;
    }

    return 0;
}

 运行结果

小李很执着理解

map就像一本字典,可以根据“键”(如名字)查找对应的“值”(如年龄)。

在上面的例子中,创建了一个名字和年龄的对应关系,并打印出来。

2.算法(Algorithm)

用于操作容器中的数据的函数集合,如排序、查找、复制、删除等。

代码示例:使用sort算法

#include <iostream>
#include <vector>
#include <algorithm>

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

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

    return 0;
}

 运行结果

小李很执着理解

sort算法可以对容器中的元素进行排序。

在上面的例子中,对一个包含随机数字的vector进行了排序,并打印出了排序后的结果。

3.迭代器(Iterator)

用于在容器中遍历元素的对象,类似于指针。常见的有forward_iteratorbidirectional_iteratorrandom_access_iterator等。

代码示例:使用iterator遍历vector

#include <iostream>
#include <vector>

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

    for (it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

 运行结果

小李很执着理解

iterator类似于指针,可以用来遍历容器中的元素。

在上面的例子中,使用iterator遍历了一个vector,并打印出了每个元素。

4.函数(Function)

STL提供了一些函数对象和仿函数,用于实现自定义的算法行为。

代码示例:使用greater仿函数

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

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

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

    return 0;
}

 运行结果

小李很执着理解

greater是一个仿函数,用来实现降序排序。

在上面的例子中,使用greater仿函数对vector进行了降序排序,并打印出了排序后的结果。

5.适配器(Adapter)

用于修改容器或仿函数行为的组件,如stackqueuepriority_queue等。

代码示例:使用stack适配器

#include <iostream>
#include <stack>

int main() {
    std::stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);

    while (!s.empty()) {
        std::cout << s.top() << " ";
        s.pop();
    }
    std::cout << std::endl;

    return 0;
}

 运行结果

小李很执着理解

stack是一种先进后出(LIFO)的数据结构,就像叠盘子,最后放的盘子最先拿出来。

在上面的例子中,往stack中添加了三个数字,并按顺序取出了这些数字。

6.分配器(Allocator)

用于管理内存分配和释放的组件。

代码示例:自定义分配器

#include <iostream>
#include <memory>
#include <vector>

template<typename T>
struct SimpleAllocator {
    typedef T value_type;

    SimpleAllocator() = default;

    template<typename U>
    SimpleAllocator(const SimpleAllocator<U>&) {}

    T* allocate(std::size_t n) {
        return static_cast<T*>(::operator new(n * sizeof(T)));
    }

    void deallocate(T* p, std::size_t) noexcept {
        ::operator delete(p);
    }
};

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

    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

 运行结果

小李很执着理解

分配器负责管理内存的分配和释放,可以自定义来满足特定需求。

在上面的例子中,实现了一个简单的分配器,并用它来创建一个vector,然后打印出了vector中的元素。

知识点:STL的六大组件各有用途,组合使用可以解决复杂的数据处理问题。

4. STL的重要性

STL在C++开发中占有重要地位,其重要性主要体现在以下几个方面:

在笔试中:STL提供的高效算法和容器常常在编程题中使用,如二叉树层序打印、重建二叉树、用两个栈实现一个队列等。

代码示例:用两个栈实现一个队列

#include <iostream>
#include <stack>

class Queue {
private:
    std::stack<int> stack1, stack2;

public:
    void enqueue(int x) {
        stack1.push(x);
    }

    int dequeue() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }

        if (stack2.empty()) {
            throw std::out_of_range("Queue is empty");
        }

        int top = stack2.top();
        stack2.pop();
        return top;
    }
};

int main() {
    Queue q;
    q.enqueue(1);
    q.enqueue(2);
    q.enqueue(3);

    std::cout << q.dequeue() << " "; // 输出1
    std::cout << q.dequeue() << " "; // 输出2
    std::cout << q.dequeue() << std::endl; // 输出3

    return 0;
}

 运行结果

小李很执着理解

通过使用两个栈,可以实现一个队列的功能,先进先出(FIFO)。

在上面的例子中,创建了一个队列,往其中添加了三个数字,并按顺序取出了这些数字。

在面试中:掌握STL是衡量C++开发者能力的重要标准之一。面试官常常通过STL相关问题考察候选人的算法能力和代码实现能力。

在工作中:STL使得开发者无需重复实现基础数据结构和算法,可以专注于业务逻辑的实现,大幅提升开发效率和代码质量。

网上有句话说:“不懂STL,不要说你会C++”。这句话充分体现了STL在C++开发中的重要性。

5. 如何学习STL

学习STL可以分为三个阶段:能用、明理、能扩展。

能用:首先要掌握STL的基本用法,了解各类容器、算法和迭代器的使用方法,并能够在实际开发中应用。

代码示例:使用vectorsort

#include <iostream>
#include <vector>
#include <algorithm>

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

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

    return 0;
}

 运行结果

小李很执着理解

学习STL的第一步是能够正确使用它的各种容器和算法。

在上面的例子中,使用了vectorsort,并打印了排序后的结果。

明理:深入理解STL的内部实现原理,了解各组件的设计思想和工作机制,掌握常见问题的解决方法。

知识点:例如,了解vector如何管理动态数组的内存,如何在内部实现扩容等。

能扩展:在掌握基础知识的基础上,能够根据具体需求对STL进行扩展或优化,如自定义分配器、实现特定算法等。

代码示例:自定义分配器

#include <iostream>
#include <memory>
#include <vector>

template<typename T>
struct SimpleAllocator {
    typedef T value_type;

    SimpleAllocator() = default;

    template<typename U>
    SimpleAllocator(const SimpleAllocator<U>&) {}

    T* allocate(std::size_t n) {
        return static_cast<T*>(::operator new(n * sizeof(T)));
    }

    void deallocate(T* p, std::size_t) noexcept {
        ::operator delete(p);
    }
};

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

    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

 运行结果

小李很执着理解

学习STL的高级阶段是能够根据需求进行扩展,比如自定义分配器。

在上面的例子中,实现了一个简单的分配器,并用它来创建一个vector

知识点学习STL不仅要会用,还要理解其原理,进而能够根据需求进行扩展。

6. STL的缺陷

虽然STL功能强大,但也存在一些缺陷:

更新速度慢:STL库的更新速度较慢。自C++98之后,中间的C++03版本仅做了一些修订,直到C++11才有进一步的更新。

缺乏线程安全:STL目前不支持线程安全。在并发环境下,开发者需要自己加锁,而且锁的粒度较大。

内部复杂:STL极度追求效率,导致内部实现比较复杂,如类型萃取、迭代器萃取等机制。

代码膨胀问题:由于模板语法的特性,STL的使用会导致代码膨胀,例如使用vector<vector<vector<int>>>这样的嵌套容器会生成多份代码。

小李很执着理解

STL虽然强大,但也有一些问题,比如更新慢、不支持线程安全、内部复杂和代码膨胀。

了解这些缺陷可以帮助在使用过程中规避潜在的问题,并根据需求做出合理的取舍和优化。

总结

总结来说,STL是C++开发中不可或缺的重要工具。掌握STL不仅能够大幅提升开发效率和代码质量,还能帮助开发者更深入地理解C++语言的精髓。在学习和使用STL的过程中,虽然会遇到一些挑战和问题,但其带来的便利和效率提升是无可替代的。

 

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

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

相关文章

振弦采集仪的工程安全监测实践与案例分析

振弦采集仪的工程安全监测实践与案例分析 振弦采集仪是一种常用的工程安全监测仪器&#xff0c;通过测量被监测结构的振动频率与振型&#xff0c;可以实时监测结构的安全状况。本文将结合实践经验和案例分析&#xff0c;探讨振弦采集仪在工程安全监测中的应用。 一&#xff0c…

前端Bug 修复手册

1.前端长整数精度丢失问题 &#xff08;1&#xff09;问题 在前后端联调时&#xff0c;发现后端有一个接口返回的值和前端页面上展示的值不一致。 后端Java实现的接口如下&#xff0c;返回一个json格式的大整数 123456789123456789&#xff1a; 但是前端请求这个接口后&…

firewalld(5)--direct

简介 direct 是 firewalld 服务的一个功能,它允许用户以更直接的方式配置防火墙规则,绕过通常的 firewalld 区域(zone)和服务的抽象层。然而,这个功能已经被弃用(deprecated),并将在未来的版本中移除。 弃用原因:直接配置可能导致与 firewalld 的其他功能(如区域和…

万界星空科技铜管加工行业MES系统解决方案

一、行业背景与挑战 随着铜管加工行业的快速发展&#xff0c;传统的管理模式已难以满足日益增长的生产需求。为满足市场的高效率、高质量、低成本要求&#xff0c;企业急需一套智能化的管理系统来提升生产效率、优化资源配置和确保产品质量。因此&#xff0c;我们针对铜管加工行…

波司登:2023/24财年业绩表现亮眼,用“新”提质推动高质量发展

2023年是全面贯彻党的二十大精神的开局之年&#xff0c;尽管国际国内经贸环境错综复杂&#xff0c;但中国经济回升向好、长期向好的基本趋势没有改变&#xff0c;新质生产力激活发展新动能&#xff0c;文化自信自强赋能国货品牌乘势而上&#xff0c;内需市场回暖向好&#xff0…

测试驱动开发(TDD)方法详解

目录 前言1. 什么是测试驱动开发1.1 TDD的基本原则1.2 TDD的优势 2. 测试驱动开发的流程2.1 编写测试2.2 运行测试2.3 编写实现代码2.4 重构代码 3. 常用工具和框架3.1 单元测试框架3.2 Mock框架3.3 集成工具 4. TDD在实际项目中的应用4.1 应用场景4.2 面临的挑战4.3 最佳实践 …

单一WiFi的RSSI指纹和行人航位推算(PDR)方法

问题背景 室内定位技术在现代生活中具有重要意义,应用广泛,如导航、物流跟踪、紧急救援等。然而,现有的室内定位技术在城市高密度平层环境中面临诸多挑战,主要包括: 多路径效应:信号在墙壁、家具等障碍物之间反射,导致信号路径复杂化。信号衰减与干扰:建筑物内的结构会…

高职人工智能专业实训课之“生成对抗网络(GAN)”

一、前言 生成对抗网络&#xff08;GAN&#xff09;作为人工智能领域的一项重要技术&#xff0c;已经在图像生成、风格迁移、数据增强等多个领域展现出巨大的潜力和应用价值。为了满足高职院校对GAN专业实训课程的需求&#xff0c;唯众人工智能教学实训凭借其前沿的教育技术平…

名企面试必问30题(十三)——项目中遇到最大的困难和挑战

1.思路 从面试官的视角来看&#xff0c;您所遇到困难的大小能够直接反映出您水平的层次。 其一&#xff0c;如果您遇到的最大挑战是诸如保障功能上线、需求分析这类基础且偏执行的产品工作&#xff0c;那么面试官或许会给您的能力水平贴上执行者的标签。 其二&#xff0c;如果…

内容营销专家刘鑫炜:自媒体时代,网站真的落伍了吗?

自媒体时代&#xff0c;虽然自媒体平台如雨后春笋般涌现&#xff0c;为内容创作者提供了更为广阔的空间&#xff0c;但并不意味着网站已经落伍。相反&#xff0c;网站仍然是信息传播、品牌建设、电子商务等多个领域的重要载体&#xff0c;具有不可替代的作用。 网站在信息传播方…

测试:自动化测试

文章目录 概念web测试selenium的工作原理selenium的常用函数元素定位操作测试对象窗口弹窗 概念 自动化的类型很多&#xff0c;那选择哪一种测试的收益是比较好的呢&#xff1f; 这里引出一个自动化测试金字塔 理想的自动化测试金字塔表达了自动化测试的理想状态&#xff0c;…

010-GeoGebra基础篇-动态验证三角形外接圆的圆心是否可以位于三角形的外部

接下来我们将进行一些稍微高级一点操作&#xff0c;一边学习新东西的同时&#xff0c;也开始对数学、物理等内容的研究。 目录 一、项目截图二、涉及内容三、问题设置1. 问题提出2. 验证方案 三、做图步骤1. 绘制定点A、B&#xff1b;2. 绘制动点C&#xff1b;&#xff08;1&am…

mysql-5.6.26-winx64免安装版本

mysql为什么要使用免安装 MySQL 提供免安装版本主要有以下几个原因和优势&#xff1a; 便捷性&#xff1a;用户无需经历安装过程&#xff0c;直接解压即可使用。这对于需要快速部署环境或者在不支持安装权限的系统上使用MySQL非常有用。灵活性&#xff1a;免安装版允许用户将…

马斯克公布xAI Grok-2大语言模型将于8月推出;GPT-5仍需时日

&#x1f989; AI新闻 &#x1f680; 马斯克公布xAI Grok-2大语言模型将于8月推出 摘要&#xff1a;7月1日&#xff0c;马斯克在X平台宣布&#xff0c;其人工智能初创公司xAI的新大语言模型Grok-2将于8月推出。此前&#xff0c;xAI已发布了Grok-1.5和Grok-1.5 Vision模型。马…

C#/WPF 自制白板工具

随着电子屏幕技术的发展&#xff0c;普通的黑板已不再适用现在的教学和演示环境&#xff0c;电子白板应运而生。本篇使用WPF开发了一个电子白板工具&#xff0c;功能丰富&#xff0c;非常使用日常免费使用&#xff0c;或者进行再次开发。 示例代码如下&#xff1a; Stack<St…

杨万里,诚斋体的开创者

杨万里&#xff0c;字廷秀&#xff0c;号诚斋&#xff0c;生于南宋绍兴元年&#xff08;公元1127年&#xff09;&#xff0c;卒于南宋庆元二年&#xff08;公元1206年&#xff09;&#xff0c;享年79岁。在中国古代文学的璀璨星河中&#xff0c;南宋诗人杨万里以其清新脱俗、贴…

方案论证项目实现功能

文章目录 1. 场景加载2. 3D 模型2.1. 坐标转换2.2. 放置模型2.3. 调整模型2.4. 提交方案 3. 查看方案3.1. 场景还原3.2. 删除 1. 场景加载 加载Cesium的Melbourne Photogrammetry的倾斜摄影作为底图&#xff0c;本身是贴地的&#xff0c;使用 Cesium 的primitives功能加载特定…

函数---逆序输出

数字的逆序输出 记住&#xff1a; n n * 10 number % 10; number number / 10; #include <stdio.h> # include <math.h>unsigned int reverse( unsigned int number );int main() {unsigned int n;scanf("%u", &n);printf("%u\n", r…

【JVM】JVM 内存结构

程序计数器 Cpu 要不停的切换执行线程&#xff0c;所以在切换回同一个线程的时候要知道程序执行到哪了&#xff0c;程序计数器&#xff08;PC 计数器&#xff09;&#xff0c;用来存储指向下一条指令的地址&#xff0c;也就是将要执行的代码。 程序的分支、循环、跳转、异常处…

Android12 MultiMedia框架之MediaExtractorService

上节学到setDataSource()时会创建各种Source&#xff0c;source用来读取音视频源文件&#xff0c;读取到之后需要demux出音、视频、字幕数据流&#xff0c;然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的&#xff1f;这里暂时不考虑APP创建…