「STL::array」标准库容器:array(数组)介绍(C++)

概述

我们知道,C语言提供的以[]表示的数组在作为参数传入函数时会退化为指针,因此想要传入数组长度信息,通常需要额外传参。有没有什么方法解决这一问题呢?

array 是一种C++标准模板库STL中定义的一种序列容器,它提供了对数组的初步封装。

cpp 复制代码
template <class T,std::size_t N>
struct array;

array 是基于数组的数据结构,只封存了栈数组(这是它与堆数组vector的显著区别),这决定了它不是动态的,但具有良好的访问速度,实际上,它与[]原生数组是等价的,只不过作为参数时不会退化。

它同时具有原生数组的所有特性:

连续存储:元素在内存中是连续存储的,这使得访问元素非常快速。

可迭代:可以被迭代,你可以使用循环来访问它的元素。

元素容器:可以存储任何类型的元素,包括基本类型、对象、指针等。

接下来,我们介绍array类型定义的成员函数。

*注意*:本文不涉及allocator空间配置器和C++23新增的range类函数。

创建销毁

STL库提供了以下方式创建一个array。

T 表示任意类型,以size_t N表示数组长度(size_t也即无符号整数)。

|-----------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 聚合初始化 | 隐式声明 | array完全仿照原生数组,因此初始化时隐式声明的。 这意味着你可以完全以原生数组的方式初始化它。 array<T,N>arr={};代表构建长度为N的数组,全为0。 array<T,N>arr={1,2,3};代表构建长度为N的数组,前三个元素为1,2,3。 同样的, array<T,N>arr;与T arr[N];是相同的,两者内部都是未初始化的垃圾元素。 |
| 析构函数 | 隐式声明 | 与原生数组完全等价的消亡机制。 |


赋值重构

在必要时我们会对array进行重构。

|-------------|------|----------------------------------------------------------------------------------------------|
| 重载拷贝赋值= | 隐式声明 | 完全等效于结构体赋值。即以来自另一 array 的每个元素重写 array 的对应元素 (struct赋值=会将依次复制其中一个struct到另一struct,数组也不例外。) |


数据访问

array同时提供了类形式的函数访问 和数组形式的运算符访问

|---------------|------------------------|-------------------------------|
| 重载[]号访问 | operator[](int pos); | 模仿原生数组的数据访问形式,如arr[3]=5; |
| 成员函数式访问 | at(int pos); | 返回pos处元素的引用。它与[]号相同,但会检查越界。 |
| 访问头元素 | front(); | 返回头元素。 |
| 访问尾元素 | back(); | 返回尾元素。 |
| 直接访问底部 | data(); | 返回array维护的栈数组的头地址。 |


迭代器

迭代器 是c++STL库提供的指向容器的类型,有着类似指针的作用。

在此处,array的迭代器几乎与原生数组的指针无异。

通常定义arrat<T>::iterator it=.....来获得一个指向array某处的it迭代器。

|-------------|------------|-----------------------------------------------------------------------------------|
| 头位置 | begin(); | 返回头位置(vector第一个元素的位置,vector为空时和end相等)。 |
| 尾位置 | end(); | 返回尾位置。(它指向的位置是第一个不属于vector的位置而不是vector的最后一个元素。) |
| 常量头位置 | cbegin(); | 返回头位置,赋值给const_iterator类型。这种迭代器不可修改容器。 |
| 常量尾位置 | cend(); | 返回常量尾位置。 |
| 逆序头位置 | rbegin(); | 返回逆序头位置,赋值给reverse_iterator类型。指向最后一个元素(与end不同),对逆序迭代器的++操作会使其向头部移动,--向尾部移动(与正序相反) |
| 逆序尾位置 | rend(); | 返回逆序尾位置,指向vector前面的那个不属于vector的位置(与front不同) |
| 常量逆序头位置 | crbegin(); | 返回常量逆序头位置,赋值给const_reverse_iterator类型。 |
| 常量逆序尾位置 | crend(); | 返回常量逆序尾位置。 |


内存管理

保持原生数组内存可知是stl封装array的主要目的之一。

|------------|-------------|------------------------------|
| 判断是否为空 | empty(); | size==0时返回true,否则返回false。 |
| 获取实际长度 | size(); | 返回N。 |
| 获取最大长度 | max_size(); | 依旧返回N。(因为栈数组可用的最大长度就是它的实际长度) |


数据控制

array类型支持通过成员函数维护数据。

|--------|-------------------------|-------------------|
| 填充 | fill(const T& target); | 将数组元素全部修改为target。 |
| 交换 | swap(array& another); | 交换两个容器的元素。 |


Tips

array<T,0>,零长数组是有意义的,

在msvc平台(visual studio等),对于array<T,0>具有一个偏特化,对他的任何读取行为都是违法的,非读取的成员函数则是一个空函数。

相关推荐
幺零九零零1 分钟前
【C++】socket套接字编程
linux·服务器·网络·c++
肘击鸣的百k路4 分钟前
Java 代理模式详解
java·开发语言·代理模式
捕鲸叉14 分钟前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点30 分钟前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
真的想不出名儿33 分钟前
Java基础——反射
java·开发语言
努力编程的阿伟1 小时前
【Java SE语法】抽象类(abstract class)和接口(interface)有什么异同?
java·开发语言
Dola_Pan1 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法
包饭厅咸鱼1 小时前
QML----复制指定下标的ListModel数据
开发语言·数据库
bryant_meng1 小时前
【python】Distribution
开发语言·python·分布函数·常用分布
红黑色的圣西罗1 小时前
Lua 怎么解决闭包内存泄漏问题
开发语言·lua