手记

STL基础教程:轻松掌握C++标准模板库

概述

C++标准模板库(STL)通过提供容器、算法与迭代器,极大地提升了C++编程效率与代码质量,简化了数据结构与算法实现,增强代码复用性与性能,是C++开发者不可或缺的工具。

引入C++标准模板库(STL)

C++标准模板库(STL)是一组用于简化编程任务的模板,提供了容器、算法和迭代器,帮助开发者以更高效的方式处理数据和任务。STL极大地提升了C++的可维护性和可复用性,使得程序员能够更加专注于业务逻辑的实现而非基础数据结构和算法。

STL对C++编程的提升

STL的引入为C++带来了一系列优势,包括:

  1. 代码复用性:通过预定义的模板,开发者可以重用代码块,减少重复劳动。
  2. 功能丰富:提供了丰富的容器、算法和迭代器,降低了开发复杂数据处理和算法的难度。
  3. 高性能:STL组件通常由编译器内联实现,性能出色。
  4. 易于学习:STL的设计遵循了现代编程原则,使得学习者能够快速掌握其核心概念。
STL容器的使用

vector容器的定义与操作

vector是STL中的一种动态数组,能够自动调整大小以适应添加或删除元素的需求。以下是一个简单的vector使用示例:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5}; // 初始化一个整数向量

    // 访问元素
    std::cout << "第一个元素: " << numbers[0] << std::endl;

    // 添加元素
    numbers.push_back(6); // 向末尾添加元素
    std::cout << "添加元素后的向量: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 删除元素
    numbers.erase(numbers.begin() + 2); // 删除索引为2的元素
    std::cout << "删除元素后的向量: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

string类的用法与特性

string是C++的一个类,用于表示可变长度的字符序列。以下是一个使用string的例子:

#include <iostream>
#include <string>

int main() {
    std::string greeting = "Hello, ";
    std::string name = "World!";
    std::string fullMessage = greeting + name; // 使用+运算符连接字符串

    std::cout << "完整消息: " << fullMessage << std::endl;

    // 访问字符串中的字符
    std::cout << "第一个字符: " << fullMessage[0] << std::endl;

    return 0;
}

listdeque的区别与使用场景

  • list:一个双链表结构的容器,其元素是顺序排列的。list在插入和删除操作上较为高效,尤其是在元素需要频繁插入或删除的场景下。
#include <iostream>
#include <list>

int main() {
    std::list<int> numbers = {1, 2, 3, 4, 5};
    numbers.push_back(6); // 在末尾添加元素

    // 遍历并输出列表
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}
  • deque:一种双端队列,支持在两端高效的插入和删除操作。deque适合需要在两端频繁操作的场景。
#include <iostream>
#include <deque>

int main() {
    std::deque<int> numberDeque = {1, 2, 3, 4, 5};
    numberDeque.push_front(0); // 在头部添加元素

    // 遍历并输出deque
    for (int num : numberDeque) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}
STL算法详解

基本算法(如sortreverse

sort函数用于对容器进行排序,reverse则用于反转容器内元素的顺序。

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

int main() {
    std::vector<int> numbers = {5, 3, 1, 4, 2};
    std::sort(numbers.begin(), numbers.end()); // 对向量进行排序
    std::reverse(numbers.begin(), numbers.end()); // 反转向量

    // 输出排序和反转后的向量
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

容器操作算法(如resizeclear

resize用于修改容器大小,clear用于清空容器中的所有元素。

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    numbers.resize(3); // 将容器大小调整为3
    numbers.clear(); // 清空容器

    // 输出清理后的容器
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

搜索与查找算法(如findsearch

find用于查找特定元素在容器中的位置,search用于查找一个序列在另一个序列中首次出现的位置。

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

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    auto it = std::find(numbers.begin(), numbers.end(), 3); // 查找值为3的元素

    if (it != numbers.end()) {
        std::cout << "找到元素,位置: " << std::distance(numbers.begin(), it) << std::endl;
    } else {
        std::cout << "未找到元素" << std::endl;
    }

    return 0;
}
STL迭代器的使用

迭代器概念与分类

迭代器是STL提供的访问容器元素的接口,分为输入迭代器、输出迭代器、前向迭代器、随机访问迭代器等,它们提供了不同级别的访问权限。

使用迭代器遍历容器

迭代器可以用于遍历容器的元素。

#include <iostream>
#include <vector>

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

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

    return 0;
}

迭代器重载与自定义迭代器类

自定义迭代器类可以实现特定的访问模式或功能。

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

template <typename T>
class MyIterator {
public:
    using value_type = T;
    using reference = T&;
    using pointer = T*;
    using iterator_category = std::bidirectional_iterator_tag;
    using difference_type = std::ptrdiff_t;

    MyIterator(T* ptr) : _ptr(ptr) {}

    bool operator==(const MyIterator& other) const {
        return _ptr == other._ptr;
    }

    bool operator!=(const MyIterator& other) const {
        return !(*this == other);
    }

    reference operator*() const {
        return *_ptr;
    }

    pointer operator->() const {
        return _ptr;
    }

    MyIterator& operator++() {
        ++_ptr;
        return *this;
    }

    MyIterator operator++(int) {
        MyIterator temp = *this;
        ++_ptr;
        return temp;
    }

    MyIterator& operator--() {
        --_ptr;
        return *this;
    }

    MyIterator operator--(int) {
        MyIterator temp = *this;
        --_ptr;
        return temp;
    }

private:
    T* _ptr;
};

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

    MyIterator<int> it(numbers.data());
    MyIterator<int> end(numbers.data() + numbers.size());

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

    return 0;
}
STL适配器与函数对象

适配器概念与常见适配器介绍

适配器用于将不兼容的对象转化为STL容器和算法可以操作的形式。

函数对象(如functionbind)的使用

函数对象允许将函数绑定到特定上下文或参数,从而实现回调、事件处理等功能。

#include <iostream>
#include <functional>

int main() {
    std::function<void()> func = []() {
        std::cout << "Hello, function object!" << std::endl;
    };

    func(); // 执行绑定的函数

    return 0;
}

适应器与函数对象在实际编程中的应用案例

实际应用中,适配器和函数对象常用于事件监听、回调机制等场景。

#include <iostream>
#include <functional>
#include <boost/asio.hpp>

int main() {
    boost::asio::io_service io_service;

    io_service.run();

    return 0;
}
STL实例与练习

实战案例分析:使用STL解决实际问题

实现一个简单的日志系统,使用std::stringstd::vector存储日志条目,并使用std::sort按时间顺序排序日志。

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

struct LogEntry {
    std::string user;
    std::string action;
    std::string when;

    bool operator<(const LogEntry& other) const {
        return when < other.when;
    }
};

int main() {
    std::vector<LogEntry> log = {
        {"Alice", "Login", "2023-04-01 10:00"},
        {"Bob", "Logout", "2023-04-01 11:30"},
        {"Alice", "Login", "2023-04-02 09:00"}
    };

    std::sort(log.begin(), log.end()); // 按时间排序

    for (const auto& entry : log) {
        std::cout << entry.user << " " << entry.action << " " << entry.when << std::endl;
    }

    return 0;
}

练习题与代码示例(提供解答)

提供简单的练习题,包含解答,以便读者实践学习。

// 练习题:实现一个简单计算器,支持加、减、乘、除操作
#include <iostream>
#include <vector>
#include <functional>

class SimpleCalculator {
public:
    double calculate(double a, double b, char op) {
        double result = 0;
        switch (op) {
            case '+':
                result = a + b;
                break;
            case '-':
                result = a - b;
                break;
            case '*':
                result = a * b;
                break;
            case '/':
                if (b == 0) {
                    std::cout << "除数不能为0" << std::endl;
                    return 0;
                }
                result = a / b;
                break;
            default:
                std::cout << "不支持的操作符" << std::endl;
                return 0;
        }
        return result;
    }
};

int main() {
    SimpleCalculator calc;
    std::vector<std::pair<double, double>> numbers = {{10, 5}, {2, 3}, {10, 0}};
    std::vector<char> operations = {'+', '-', '/'};

    for (size_t i = 0; i < numbers.size(); ++i) {
        std::cout << "计算 " << numbers[i].first << " " << operations[i] << " " << numbers[i].second << " 的结果是: " << calc.calculate(numbers[i].first, numbers[i].second, operations[i]) << std::endl;
    }

    return 0;
}

总结与复习:巩固STL基础知识

通过实践案例和练习题,学习者可以更好地掌握STL的基础知识和应用。建议在实际开发中不断应用这些知识,通过解决实际问题来加深理解。同时,持续阅读相关文档和资源,如慕课网等平台上的课程,有助于进一步提升技能水平。

0人推荐
随时随地看视频
慕课网APP