【C/C++】- STL(ing)

目录

一、概述

二、模板

三、迭代器

1. 什么是迭代器

 【例 1】为数组容器、链表容器编制共同显示函数。

2. 进一步理解迭代器

3. STL迭代器

(1)输入迭代器:

(2)输出迭代器:

(3)前向迭代器:

(4)双向迭代器:

(5)随机访问迭代器:

四、通用容器

1. 堆和栈的区别

2. 容器分类

(1)序列性容器:

(2)关联式容器:

(3)容器适配器:

3. 容器共性

(1)一般函数

(2)顺序容器和关联容器共有函数


一、概述


 STL 主要包含容器、算法和迭代器三大部分。


 STL 容器包含了绝大多数数据结构,如数组、链表、队列、堆、栈和树等。开发者直接应用这些系统 STL 容器相关函数就可以了,而且这些函数都是带模板参数的,可以适应许多数据元素类型,功能非常强大。STL 算法包含了诸如增、删、改、查和排序等系统函数,开发者可以直接操作这些函数实现相应功能。STL 迭代器类似指针,通过它的有序移动把容器中的元素与算法关联起来,它是实现所有 STL 功能的基础所在。


当然,STL 也包含其他一些内容,如字符串,输入输出流等内容。


二、模板

模板分为函数模板类模板

模板参数声明:template<class T>

三、迭代器


迭代器是 STL 重要的核心技术,提供了统一访向容器元素的方法,为编制通用算法提供了坚实的技术基础。


1. 什么是迭代器


迭代器即是指针,可以是所需要的任意类型,它的最大好处是可以使容器和算法分离开来。例如,有两个容器类:MyArray 是某类型数组集合;MyLink 是某类型链表集合。它们都有显示、查询和排序等功能,常规思维是每个容器类中有自己的显示,查询和排序等函数。

仔细分析可得出:不同容器中完成相同功能代码的思路大体是相同的,那么能不能把它们抽象出来,多个容器仅对应一个显示、一个查询,一个排序函数呢?这是泛型思维发展的必然结果,于是迭代器思维就产生了。

 
【例 1】为数组容器、链表容器编制共同显示函数。

MyArray:

#include<stdio.h>
template<class T>
class MyArray
{
private:
int m_nTotalsize;
//数组总长度
int m_nvalidsize;
//数组有效长度
T*m_pData;
//数据
public:
MyArray(int nsize-3)
//数组默认总长度是 3
m_pData-new T[nSize];
m_nTotalsize-nSize;
m_nValidsize=0;
void Add (T value)//向m_PData添加数据
{
}
int Getsize()//返回数组有效长度
{
return m_nvalidsize;
}
T Get (int pos)
//返回某一位置元素
return m_pDatalpos);
virtual~Myarray()
{
if(m_pData!=NULL)
{
delete []m_pData;
m_pData-NULL;
}
}
}

 MyLink 单项链表类初始代码如下所示。


template <class T>
struct Unit
//链表单元
T value;
Unit* next;
田
template<class T>
class MyLink
如
Unit<T>* head;
unit<T>*tail;
unit<T>*prev;
//链表头
//链表尾
废
public;
Mylink()
head-tail-prev=NULL;
void Add (T &value)
//向链表中添加元素
Unit<T>*u-new Unit<T>();
u->value-value;

u->next=NULL;
if(head ==NULL)
head-u;
prev=u;
else
prev->next=u;
prev=u;
tail-u->next;
virtual~MyLink()
if (head!=NULL)
Unit<T>* prev=head;
Unit<T>* next=NULL;
while(prev!=tail)
next=prev->next;
delete prev;
prev=next;


可以看出,MyLink 是模板元素T的链表类,以 struct Unit 为一个个链表单元。那么如何以 MyArray MyLink 为基础完成一个共同显示函数呢?其实非常简单,先从需要出发,逆向考虑,需要先写一个泛型显示函数。



2. 进一步理解迭代器


迭代器的编程思路,如果用图形来描述:

每个容器都应有对应的迭代器,容器通过迭代器共享某一具体算法,某一具体算法不依附于某一具体的容器。迭代器起到一个中间媒介的作用,通过它把容器与算法关联起来。换一句更贴切的话来说,迭代器思维是编制通用泛型算法发展的必然结果,算法通过迭代器依次访问容器中的元素。


STL标准模板库编程的基本步骤

(1)形成容器元素;

(2)取出所需要的迭代指针:

(3)调用通用算法。

3. STL迭代器

(1)输入迭代器

        istream_iterator

(2)输出迭代器

        ostream_iterator

(3)前向迭代器

        如replace

(4)双向迭代器

        可以向后一次移动一个位置

(5)随机访问迭代器

        具有指针的功能

四、通用容器

1. 堆和栈的区别

(1):链式存储结构,由人来生成和释放(new,malloc,relloc,free),存储数组和对象,效率低。

(2):内存区域是连续的,先进后出,存储局部变量和参数值,又计算机自动生成和使用(内存泄漏),生命周期短,效率高。

2. 容器分类

(1)序列性容器:

按照线性排列来存储某类型值的集合,每个元素都有自己特定的位 置,顺序容器主要有 vector deque 和 list,

vector

就是动态数组。它是在堆中分配内存,元素连续存放,有保留内存,如果减 少大小后内存也不会释放。新值大于当前大小时才会再分配内存。对最后元素操 作最快(在后面添加删除最快),此时一般不需要移动内存。只有保留内存不够时, 才需要对中间和开始处进行添加删除元素操作,这时需要移动内存,如果你的元素 是结构或是类,那么移动的同时还会进行构造和析构操作。vector 的一大特点是可 直接访问任何元素

vector(连续的空间存储,可以使用[操作符)快速地访向随机的元素,快速地在末尾插
入元素,但是在序列中间随机地插入,删除元素要慢。而且如果一开始分配的空间不够的
话,有一个重新分配更大空间的过程。

示例:

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

int main()
{
    using namespace std;

    创建容器
    vector<double> values; //空容器
    values.reserve(20);  //增加容量20

    vector<int> primes{ 2, 3, 5, 7, 11, 13, 17, 19 };//枚举

    vector<double> values2(20); //20个0元素

    vector<double> values3(20,1);  //20个1元素

    vector<double> values4(values3);  //复制
    
    //访问元素
    cout << values[0] << values.at(2) << values.front() << values.back();

    /// 增加、插入元素<summary>
    values.push_back('S'); 
    values.emplace_back('s');
    values.insert(values.begin(), 'T');
    values.insert(values.end(), {1.2,3.3,6.5,7,55,12,66,85,35});
    values.emplace(values.end(), 9.9);
    /// </summary>
    /// 删除元素
    values.pop_back();
    //values.erase(values.rend()-2);
    //values.clear();
    std::remove(values.begin(), values.end(), 55);
    return 0;
}

deque:

与 vector 类似,支持随机访问和快速插入删除,它在容器中某一位置上的操 作所花费的是线性时间。与 vector 不同的是,deque 还支持从开始端插人、删除数 据。由于它主要对前端,后端进行操作,因此也叫做双端队列

deque(小片的连续,小片间用链表相连,实际上内部有一个 map 的指针,因为知道类
型,所以还是可以使用门,只是速度没有 vector快)快速地访问随机的元素,快速地在开始
和末尾插入元素,随机地插入、删除元素要慢,空间的重新分配要比 vector 快
,重新分配空
间后,原有的元素不需要备份。对 deque 的排序操作,可将 deque 先复制到 vector,排序后
再复制回 deque。

 list:

又叫链表,是一种双线性列表,只能顺序访问(从前向后或者从后向前),与前面 两种容器类有一个明显的区别就是它不支持随机访问。要访向表中某个下标处的 项需要从表头或表尾处(接近该下标的一端)开始循环。

list(每个元素间用链表相连)访问随机元素不如 vector 快,随机地插人元素比 vector
,对每个元素分配空间,所以不存在空间不够,重新分配的情况。

 示例:

(2)关联式容器:

与前面讲到的顺序容器相比,关联式容器更注重快速和高效地检索 数据的能力。这些容器是根据键值(key)来检索数据的,键可以是值也可以是容器中的某一 成员。这一类中的成员在初始化后都是按一定顺序排好序的。关联式容器主要有 set, multiset.map 和 multimap

•set:快速查找,不允许重复值。

set 内部元素唯一,用一棵平衡树结构来存储,因此遍历的时候就排序了,查找也比
较快。


• multiset:快速查找,允许重复值。
• map:一对一映射,基于关键字快速查找,不允许重复值。

map 一对一地映射结合,key 不能重复。


•multimap:一对多映射,基于关键字快速查找,允许重复值。


(3)容器适配器:

对已有的容器进行某些特性的再封装,不是一个真正的新容器。1
要有 stack、queue


stack:堆栈类,特点是后进先出。


• queue:队列类,特点是先进先出。


3. 容器共性


(1)一般函数


•默认构造函数:提供容器默认初始化的构造函数。
•复制构造函数:将容器初始化为现有同类容器副本的构造函数。
•析构函数
:不再需要容器时进行内存整理的析构函数。


• empty:            容器中没有元素时返回 true,否则返回 false。
•max_size:     返回容器中最大元素个数。
• size:              返回容器中当前元素个数。
•operator一:    将一个容器赋给另一个容器。
•operator<:        如果第一个容器小于第二个容器,返回 true,否则返回 false。
•operator<一:     如果第一个容器小于或等于第二个容器,返回 true,否则返回 false,
•operator>:         如果第一个容器大于第二个容器,返回 true,否则返回 false。
•operator>一:     如果第一个容器大于或等于第二个容器,返回 true,否则返回 false,
•operator==:    如果第一个容器等于第二个容器,返回 true,否则返回 false。
• operator!=:      如果第一个容器不等于第二个容器,返回 true,否则返回 false。
• swap:             交换两个容器的元素。


(2)顺序容器和关联容器共有函数


• begin:该函数有两个版本,返回 iterator 或 const_iterator,返回容器第一个元素选
代器指针。


• end:该函数有两个版本,返回 iterator 或 const_iterator,返回容器最后一个元素剧
面一位的迭代器指针。


• rbegin:该函数有两个版本,返回 reverse_iterator 或 const_reverse_iterator,返回答
器最后一个元素的迭代器指针。


• rend:该函数有两个版本,返回 reverse_iterator 或 const_reverse_iterator,返回容料
首个元素前面一位的迭代器指针。


• erase:从容器中清除一个或几个元素。


• clear:清除容器中所有元素。







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这些都是 Android NDK 内部的 `Android.mk` 文件。其中,`./android-ndk-r25c/sources/android/native_app_glue/Android.mk` 是用于编译 Native Activity 示例应用程序的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/support/Android.mk` 是包含一些 Android 支持库的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/ndk_helper/Android.mk` 是包含一些辅助函数和类的 `Android.mk` 文件;`./android-ndk-r25c/sources/android/cpufeatures/Android.mk` 是用于编译 `cpufeatures` 库的 `Android.mk` 文件,该库提供了一些 CPU 相关的信息和功能;`./android-ndk-r25c/sources/cxx-stl/llvm-libc++abi/Android.mk` 和 `./android-ndk-r25c/sources/cxx-stl/llvm-libc++/Android.mk` 是用于编译 C++ STL 库的 `Android.mk` 文件,分别对应 libc++abi 和 libc++ 两个 STL 库;`./android-ndk-r25c/sources/third_party/googletest/Android.mk` 是用于编译 Google Test 测试框架的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/Android.mk` 是用于编译 Shaderc 编译器的 `Android.mk` 文件,该编译器可以将 GLSL 代码编译成 SPIR-V 代码;`./android-ndk-r25c/sources/third_party/shaderc/libshaderc/Android.mk` 是用于编译 Shaderc 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/libshaderc_util/Android.mk` 是用于编译 Shaderc Util 库的 `Android.mk` 文件,该库提供了一些辅助函数和类;`./android-ndk-r25c/sources/third_party/shaderc/third_party/Android.mk` 是用于编译 Shaderc 编译器依赖的第三方库的 `Android.mk` 文件,包括 glslang 和 spirv-tools 两个库;`./android-ndk-r25c/sources/third_party/shaderc/third_party/glslang/Android.mk` 是用于编译 glslang 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/shaderc/third_party/spirv-tools/Android.mk` 是用于编译 spirv-tools 库的 `Android.mk` 文件;`./android-ndk-r25c/sources/third_party/vulkan/src/build-android/jni/Android.mk` 是用于编译 Vulkan 库的 `Android.mk` 文件。 如果您要在 Android NDK 中编写自己的 `Android.mk` 文件,可以参考这些示例文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁荣生长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值