您的位置:首页 > 教育 > 锐评 > 青岛出版集团网站_机加工订单网_公关公司提供的服务有哪些_网络运营主要做什么工作

青岛出版集团网站_机加工订单网_公关公司提供的服务有哪些_网络运营主要做什么工作

2025/2/28 12:58:58 来源:https://blog.csdn.net/weixin_74085818/article/details/144412002  浏览:    关键词:青岛出版集团网站_机加工订单网_公关公司提供的服务有哪些_网络运营主要做什么工作
青岛出版集团网站_机加工订单网_公关公司提供的服务有哪些_网络运营主要做什么工作

本专栏目的

  • 更新C/C++的基础语法,包括C++的一些新特性

前言

  • STL无疑是C++史上一个重要的发明,未来我将更新STL有关的知识点,入门绝对够了(看目录就知道了👀)
  • 这是第一篇,讲STL、迭代器
  • C语言后面也会继续更新知识点,如内联汇编;
  • 欢迎收藏 + 关注,本人将会持续更新。

文章目录

  • STL基本概念
        • 容器
        • 算法
        • 迭代器
  • 迭代器
    • 数组范围指针
    • 自定义容器(练习,理解迭代器)
      • MyArray
        • 另一种遍历方式
        • 修改版一种遍历方式
    • 迭代器类

STL基本概念

STL:标准模板类库

  • 容器篇: 封装好的数据结构 用来存储或者操作数据
  • 迭代器篇:遍历容器的(内置类)
  • 仿函数: 排序准则,比较准则
  • 算法篇: 特殊操作的容器(排序,查找…)

STL需要掌握的内容

  • 学会创建对象
  • 学会访问数据
  • 学会去看标准库的类以及类中的一些成员函数

STL六大件:

  • 容器(Container)

  • 算法(Algorithm)

  • 迭代器(iterator)

  • 仿函数(Function object)

  • 适配器(Adaptor)

  • 空间配制器(allocator)

在C++标准中,STL被组织为下面的13个头文 件:<algorithm>、<deque>、<functional>、<iter>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack> 和<utility>。

容器

概念:封装好的数据结构

STL中,容器主要分为序列式容器关联式容器

序列式容器:即以线性排列(类似普通数组的存储方式)来存储某一指定类型(例如 int、double 等)的数据,该类容器并不会自动对存储的元素按照值的大小进行排序

关联式容器:非线性排列,在存储元素时会为每个元素在配备一个键,整体以键值对的方式存储到容器中,可以通过键值直接找到对应的元素,而无需遍历整个容器,另外,关联式容器在存储元素,默认会根据各元素键值的大小做升序排序

算法

STL算法分为:质变算法非质变算法

质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等

非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等

迭代器

迭代器:是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物。

作用:连接算法与容器,在STL中,实现了算法和容器相分离的特点,迭代像一个桥梁,连通了算法与容器。

迭代器的种类:

种类功能操作
输入迭代器提供对数据的只读访问只读,支持++、==、!=
输出迭代器提供对数据的读写访问读写,支持++
前向迭代器提供读写操作,并能向前推进迭代器读写,支持++、==、!=
双向迭代器提供读写操作,并能向前和向后操作读写,支持++、–,
随机访问迭代器提供读写操作,并能以跳跃的方式访问容器的任意数据,是功能最强的迭代器读写,支持++、–、[n]、-n、<、<=、>、>=

迭代器

简而言之,迭代器的作用是用来访问容器中的元素的, 可以理解为指针。

数组范围指针

以数组遍历为例:

//容器
int arr[5] = { 1,2,3,4,5 };
  • 下标法遍历
for (int i = 0; i < 5; i++)
{cout << arr[i] << " ";
}
  • 基于范围的for循环
for(auto& v : arr)
{cout << v << " ";
}

☑️ 提问 为啥能使用基于范围的for循环遍历数组呢?

因为只要知道了数组的开始和结束就能去遍历了,如下:

  • 指针法遍历
int* iter = arr;
for (iter = arr; iter != arr + 5; iter++)
{cout << *iter << " ";
}
  • 迭代器方式
using  iterator = int*;
iterator begin = arr;
iterator end = arr + 5;
for (iterator it = begin; it != end; it++)
{cout << *it << " ";
}

自定义容器(练习,理解迭代器)

MyArray

🏚 我们先自己写一个MyArray容器。(满足基于类型的for循环,则支持一点简单的迭代器)

template<typename _T, size_t _size>
class MyArray
{
public:MyArray(std::initializer_list<_T> arr){int i = 0;for (auto v : arr) {m_array[i++] = v;}}_T& operator[](size_t index) {return m_array[index];}private:_T m_array[_size]{ _T() };
};

在上面的代码中,我们提供了size()和[]运算符重载,所以可以通过下标去遍历SArray。

MyArray<int, 10> array = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };for (int i = 0; i < 10; i++) {std::cout << array[i] << " ";
}
std::cout << std::endl;
另一种遍历方式

那么对于SArray来说,能使用基于范围的for循环吗?

  • 基于范围的for循环是方便访问容器。基于范围的for循环又需要begin和end函数才能工作
for (auto& v : nums)
{cout << v << " ";
}

报错了!

在这里插入图片描述

它说,没有找到begin和end函数,有由于基于范围的for循环又需要begin和end函数才能工作.

那么begin和end函数是什么呢?

其实就是数组开始的指针和结束的指针,🎃 解决方法: 加上beginend函数,如下:

// : 本质,有begin和end地址[ )
_T* begin() {return m_array;
}
_T* end() {return m_array + _size;
}

在这里插入图片描述

修改版一种遍历方式

这一种方式,就是讲上面的函数进行修改,修改如下:

using iterator = _T*;
iterator begin() {return m_array;
}
iterator end() {return m_array + _size;
}

这个时候,就可以这样遍历了,如下:

for (MyArray<int, 10>::iterator it = array.begin(); it != array.end(); it++) {std::cout << *it << " ";
}
std::cout << "\n";

在这里插入图片描述

这种方法看起来有点复杂,==但是,==这个就是迭代器(iterator),看着很复杂,但是随着后面学习,就会发现这样好处也有很多,最明显的一点就是:获取元素指针方便了。

其他: 上面说到,迭代器有很多种,接下来我们来看一下这个案例:

// 加const修饰
const MyArray<int, 10> array = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };for (auto v : array) {std::cout << v << " ";
}
std::cout << std::endl;

这个时候,有出问题了,如下:

在这里插入图片描述

👀 解释: 找不到对应的beginend,因为这个对象用了const修饰,那我们就写一版本的带const

beginend,如下:

using const_iterator = const _T*;
const_iterator begin() const {return m_array;
}
const_iterator end()const {return m_array + _size;
}

在这里插入图片描述

迭代器有很多不同的种类,不同的种类对应着不同的应用场景,需要多用、多写,熟悉之后可以参考:侯捷老师STL源码讲解

迭代器类

在C++STL中,基本上所有迭代器都是通过类来实现的,这样就非常方便的去处理遍历操作了,这里写一个含迭代器类的链表(参考某一位大神):

#include <iostream>template<typename T>
class _SForwardList_iterator;template<typename T>
struct Node
{Node(const T& v) :data(v), next{ nullptr } {}T data;Node* next;
};template<typename T>
class SForwardList
{
public:SForwardList() {}SForwardList(const std::initializer_list<T>& list){for (auto& v : list){push_back(v);}}~SForwardList(){Node<T>* curNode = _head;Node<T>* delNode = nullptr;while (curNode){delNode = curNode;curNode = curNode->next;delete[] delNode;}}void push_back(const T& value){Node<T>* node = new Node<T>(value);if (!_head){_head = node;_tail = node;}else{_tail->next = node;_tail = node;}}friend std::ostream& operator<<(std::ostream& out, const SForwardList& list){Node<T>* curNode = list._head;out << "SForwardList(";while (curNode){out << curNode->data;if (curNode->next)out << ",";curNode = curNode->next;}out << ")";return out;}using iterator = _SForwardList_iterator<T>;iterator begin() { return iterator(_head); }iterator end() { return iterator(nullptr); }private:Node<T>* _head{ nullptr };Node<T>* _tail{ nullptr };
};template<typename T>
class _SForwardList_iterator {
public:_SForwardList_iterator() : _ptr(nullptr) {}explicit _SForwardList_iterator(Node<T>* ptr) : _ptr(ptr) {}bool operator!=(const _SForwardList_iterator& it) const {return _ptr != it._ptr;}_SForwardList_iterator& operator++() {if (_ptr) _ptr = _ptr->next;return *this;}T& operator*() const {return _ptr->data;}private:Node<T>* _ptr;
};int main()
{SForwardList<int> list = { 1,2,3,4,5,6,7,8 };for (auto v : list) {std::cout << v << " ";}return 0;
}

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com