C++进阶教程:C++ 标准模板库初学者指南("C++进阶必备:标准模板库(STL)新手入门指南")

原创
ithorizon 6个月前 (10-20) 阅读数 14 #后端开发

C++进阶必备:标准模板库(STL)新手入门指南

一、引言

在C++的学习过程中,标准模板库(Standard Template Library,简称STL)是一个非常重要的部分。STL为C++程序员提供了一系列模板化的数据结构和算法,允许代码更加简洁、高效。本文将为您介绍STL的基本概念、常用组件及其使用方法,帮助新手飞速入门。

二、STL概述

STL重点包括以下几个部分:

  • 容器(Containers):提供了一种存储数据集合的方法。
  • 迭代器(Iterators):提供了一种访问容器中元素的方法。
  • 算法(Algorithms):提供了一系列用于操作数据的函数。
  • 函数对象(Function Objects):是一种特殊的函数,可以存储在容器中并像普通对象一样使用。
  • 适配器(Adapters):用于扩展或修改已有容器或算法的功能。

三、STL容器

STL提供了多种容器,包括序列容器、相关性容器和适配器容器。下面分别介绍它们的用法。

3.1 序列容器

序列容器包括vector、deque、list、forward_list和array。下面分别介绍它们的特性和用法。

3.1.1 vector

vector是一个动态数组,可以按照需要动态地改变大小。

#include

#include

int main() {

std::vector v;

v.push_back(1);

v.push_back(2);

v.push_back(3);

for (int i = 0; i < v.size(); ++i) {

std::cout << v[i] << " ";

}

std::cout << std::endl;

return 0;

}

3.1.2 deque

deque是一个双端队列,可以在两端插入和删除元素。

#include

#include

int main() {

std::deque d;

d.push_front(1);

d.push_back(2);

d.push_back(3);

for (auto it = d.begin(); it != d.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.1.3 list

list是一个双向链表,可以在任意位置插入和删除元素。

#include

#include

int main() {

std::list l = {1, 2, 3};

for (auto it = l.begin(); it != l.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.1.4 forward_list

forward_list是一个单向链表,仅拥护单向遍历。

#include

#include

int main() {

std::forward_list fl = {1, 2, 3};

for (auto it = fl.begin(); it != fl.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.1.5 array

array是一个固定大小的数组,类似于C风格的数组。

#include

#include

int main() {

std::array a = {1, 2, 3};

for (int i = 0; i < a.size(); ++i) {

std::cout << a[i] << " ";

}

std::cout << std::endl;

return 0;

}

3.2 相关性容器

相关性容器包括set、multiset、map、multimap、unordered_set、unordered_multiset、unordered_map和unordered_multimap。下面分别介绍它们的特性和用法。

3.2.1 set

set是一个有序集合,存储唯一的元素。

#include

#include

int main() {

std::set s = {1, 2, 2, 3};

for (auto it = s.begin(); it != s.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.2.2 multiset

multiset是一个有序集合,可以存储多个相同的元素。

#include

#include

int main() {

std::multiset ms = {1, 2, 2, 3};

for (auto it = ms.begin(); it != ms.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.2.3 map

map是一个有序映射,存储键值对。

#include

#include

int main() {

std::map m = {{1, "one"}, {2, "two"}, {3, "three"}};

for (auto it = m.begin(); it != m.end(); ++it) {

std::cout << it->first << ": " << it->second << std::endl;

}

return 0;

}

3.2.4 multimap

multimap是一个有序映射,可以存储多个具有相同键的元素。

#include

#include

int main() {

std::multimap mm = {{1, "one"}, {2, "two"}, {2, "two2"}, {3, "three"}};

for (auto it = mm.begin(); it != mm.end(); ++it) {

std::cout << it->first << ": " << it->second << std::endl;

}

return 0;

}

3.2.5 unordered_set

unordered_set是一个无序集合,存储唯一的元素。

#include

#include

int main() {

std::unordered_set us = {1, 2, 2, 3};

for (auto it = us.begin(); it != us.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.2.6 unordered_multiset

unordered_multiset是一个无序集合,可以存储多个相同的元素。

#include

#include

int main() {

std::unordered_multiset ums = {1, 2, 2, 3};

for (auto it = ums.begin(); it != ums.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

3.2.7 unordered_map

unordered_map是一个无序映射,存储键值对。

#include

#include

int main() {

std::unordered_map um = {{1, "one"}, {2, "two"}, {3, "three"}};

for (auto it = um.begin(); it != um.end(); ++it) {

std::cout << it->first << ": " << it->second << std::endl;

}

return 0;

}

3.2.8 unordered_multimap

unordered_multimap是一个无序映射,可以存储多个具有相同键的元素。

#include

#include

int main() {

std::unordered_multimap umm = {{1, "one"}, {2, "two"}, {2, "two2"}, {3, "three"}};

for (auto it = umm.begin(); it != umm.end(); ++it) {

std::cout << it->first << ": " << it->second << std::endl;

}

return 0;

}

3.3 适配器容器

适配器容器包括stack、queue、priority_queue、stack适配器、queue适配器和priority_queue适配器。下面分别介绍它们的特性和用法。

3.3.1 stack

stack是一个后进先出(LIFO)的容器。

#include

#include

int main() {

std::stack 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;

}

3.3.2 queue

queue是一个先进先出(FIFO)的容器。

#include

#include

int main() {

std::queue q;

q.push(1);

q.push(2);

q.push(3);

while (!q.empty()) {

std::cout << q.front() << " ";

q.pop();

}

std::cout << std::endl;

return 0;

}

3.3.3 priority_queue

priority_queue是一个优先队列,元素按照优先级排序。

#include

#include

#include

int main() {

std::priority_queue pq;

pq.push(1);

pq.push(3);

pq.push(2);

while (!pq.empty()) {

std::cout << pq.top() << " ";

pq.pop();

}

std::cout << std::endl;

return 0;

}

四、STL迭代器

迭代器是一种抽象指针,用于访问容器中的元素。STL提供了多种迭代器,包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。下面分别介绍它们的用法。

4.1 输入迭代器

输入迭代器只能用于读取元素,不能修改元素。

#include

#include

int main() {

std::vector v = {1, 2, 3};

std::vector::iterator it = v.begin();

while (it != v.end()) {

std::cout << *it << " ";

++it;

}

std::cout << std::endl;

return 0;

}

4.2 输出迭代器

输出迭代器只能用于写入元素,不能读取元素。

#include

#include

int main() {

std::vector v = {1, 2, 3};

std::vector::iterator it = v.begin();

std::cout << "Output iterator: ";

while (it != v.end()) {

std::cout << *it << " ";

++it;

}

std::cout << std::endl;

return 0;

}

4.3 前向迭代器

前向迭代器可以读取和修改元素,但不能双向遍历。

#include

#include

int main() {

std::list l = {1, 2, 3};

std::list::iterator it = l.begin();

while (it != l.end()) {

std::cout << *it << " ";

++it;

}

std::cout << std::endl;

return 0;

}

4.4 双向迭代器

双向迭代器可以读取和修改元素,并拥护双向遍历。

#include

#include

int main() {

std::deque d = {1, 2, 3};

std::deque::iterator it = d.begin();

while (it != d.end()) {

std::cout << *it << " ";

++it;

}

std::cout << std::endl;

return 0;

}

4.5 随机访问迭代器

随机访问迭代器可以读取和修改元素,并拥护随机访问。

#include

#include

int main() {

std::vector v = {1, 2, 3};

std::vector::iterator it = v.begin();

std::cout << "Element at index 1: " << v[1] << std::endl;

return 0;

}

五、STL算法

STL算法提供了一系列用于操作数据的函数,包括排序、查找、替换、合并、分区等。下面介绍一些常用的算法。

5.1 排序算法

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

#include

#include

#include

int main() {

std::vector v = {3, 1, 2};

std::sort(v.begin(), v.end());

for (auto it = v.begin(); it != v.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

5.2 查找算法

find算法可以在容器中查找特定元素。

#include

#include

#include

int main() {

std::vector v = {1, 2, 3, 4, 5};

auto it = std::find(v.begin(), v.end(), 3);

if (it != v.end()) {

std::cout << "Element found: " << *it << std::endl;

} else {

std::cout << "Element not found" << std::endl;

}

return 0;

}

5.3 替换算法

replace算法可以将容器中的元素替换为另一个值。

#include

#include

#include

int main() {

std::vector v = {1, 2, 3, 4, 5};

std::replace(v.begin(), v.end(), 2, 10);

for (auto it = v.begin(); it != v.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

5.4 合并算法

merge算法可以将两个有序容器合并为一个有序容器。

#include

#include

#include

int main() {

std::vector v1 = {1, 3, 5};

std::vector v2 = {2, 4, 6};

std::vector v3;

std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v3));

for (auto it = v3.begin(); it != v3.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

5.5 分区算法

partition算法可以将容器中的元素按照条件分为两个部分。

#include

#include

#include

bool is_odd(int x) {

return x % 2 != 0;

}

int main() {

std::vector v = {1, 2, 3, 4, 5};

std::partition(v.begin(), v.end(), is_odd);

for (auto it = v.begin(); it != v.end(); ++it) {

std::cout << *it << " ";

}

std::cout << std::endl;

return 0;

}

六、STL函数对象

函数对象是一种特殊的函数,可以存储在容器中并像普通对象一样使用。下面介绍两种常用的函数对象。

6.1 函数对象

函数对象是一个重载了operator()的类。

#include

#include

#include

class Print {

public:

void operator()(int x) {

std::cout << x << " ";

}

};

int main() {

std::

本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门