「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>具有一个偏特化,对他的任何读取行为都是违法的,非读取的成员函数则是一个空函数。

相关推荐
无 证明31 分钟前
new 分配空间;引用
数据结构·c++
Kisorge1 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学3 小时前
QT-简单视觉框架代码
开发语言·qt
威桑3 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服3 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans3 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手3 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#