「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 arrN;是相同的,两者内部都是未初始化的垃圾元素。 |
| 析构函数 | 隐式声明 | 与原生数组完全等价的消亡机制。 |


赋值重构

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

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


数据访问

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

|---------------|------------------------|-------------------------------|
| 重载\[\]号访问 | operator\[\](int pos); | 模仿原生数组的数据访问形式,如arr3=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>具有一个偏特化,对他的任何读取行为都是违法的,非读取的成员函数则是一个空函数。

相关推荐
陌路20几秒前
C++高级进阶--夯实进阶基础(1)
开发语言·c++
梦想三三17 分钟前
【PYthon词频统计与文本向量化】苏宁易购评论分析实战
开发语言·python
AI人工智能+电脑小能手19 分钟前
【大白话说Java面试题 第93题】【Mysql篇】第23题:从查找速度来看,聚集索引和非聚集索引哪个更快?
java·开发语言·数据库·mysql·面试
Cheng小攸1 小时前
入侵检测环境部署
开发语言·php
郝学胜-神的一滴1 小时前
中级OpenGL教程 008:精准控制高光光斑大小与强度
c++·unity·godot·three.js·图形学·opengl·unreal
我是唐青枫1 小时前
Java MyBatis-Flex 实战指南:从 BaseMapper 到 QueryWrapper 的轻量 ORM 用法
java·开发语言·mybatis
牢姐与蒯2 小时前
c++数据结构之c++11(一)
数据结构·c++
ShyanZh2 小时前
Markitdown 多格式文档智能解析实战指南
开发语言·c#
一只专注api接口开发的技术猿2 小时前
OpenClaw 对接淘宝商品 API,低成本实现全天候选品监控|附可运行 Python 实操代码
大数据·开发语言·数据库·python
xingpanvip2 小时前
星盘接口开发文档:马盘次限盘接口指南
android·开发语言·python·php·lua