C++ STL array容器

一、前言

array 容器是 C++ 11 标准中新增的序列容器,就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。在使用上,它比普通数组更安全,且效率并没有因此变差。
和其它容器不同,array 容器的大小是固定的,无法动态的扩展或收缩,只允许访问或者替换存储的元素。

二、详解

array 容器以类模板的形式定义在 <array> 头文件,并位于命名空间 std 中。因此,在使用该容器之前,代码中需引入 <array> 头文件,并默认使用 std 命令空间。即:

#include <array>
using namespace std;

在 array<T,N> 类模板中,T 用于指明容器中的存储的具体数据类型,N 用于指明容器的大小,N 必须是常量,不能用变量表示

1、初始化

① std::array<int, 10> values; 
② std::array<int, 10> values {};
③ std::array<double, 10> values {2,1,4,9};

以上都可以对array进行初始化,区别在于:
①各个元素的值是不确定的(array 容器不会做默认初始化操作)
②将所有的元素初始化为 0 或者和默认元素类型等效的值
③可以初始化一部分值,剩余的均初始化值默认为0

2、成员函数

成员函数功能
begin()返回指向容器中第一个元素的随机访问迭代器
end()返回指向容器最后一个元素之后一个位置的随机访问迭代器,通常和 begin() 结合使用
rbegin()返回指向最后一个元素的随机访问迭代器
rend()返回指向第一个元素之前一个位置的随机访问迭代器
cbegin()和 begin() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素
cend()和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素
crbegin()和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素
crend()和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素
size()返回容器中当前元素的数量,其值始终等于初始化 array 类的第二个模板参数 N
max_size()返回容器可容纳元素的最大数量,其值始终等于初始化 array 类的第二个模板参数 N
empty()判断容器是否为空,和通过 size()==0 的判断条件功能相同,但其效率可能更快
at(n)返回容器中 n 位置处元素的引用,该函数自动检查 n 是否在有效的范围内,如果不是则抛出 out_of_range 异常
front()返回容器中第一个元素的直接引用,该函数不适用于空的 array 容器
back()返回容器中最后一个元素的直接应用,该函数同样不适用于空的 array 容器。
data()返回一个指向容器首个元素的指针。利用该指针,可实现复制容器中所有元素等类似功能
fill(val)将 val 这个值赋值给容器中的每个元素
array1.swap(array2)交换 array1 和 array2 容器中的所有元素,但前提是它们具有相同的长度和类型

3、实例

1)初始化

// testArray.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <array>
using namespace std;

int main()
{
    std::array<int, 5> arrayInt;
    std::array<int, 5> arrayInt2{};
    std::array<int, 5> arrayInt3{ 2,6,4,3 };

    //遍历array的值
    for (int i = 0; i < arrayInt.size(); i++) {
        std::cout << "输出arrayInt[" << i << "]=" << arrayInt[i] << std::endl;
    }

    for (int i = 0; i < arrayInt2.size(); i++) {
        std::cout << "输出arrayInt2[" << i << "]=" << arrayInt2[i] << std::endl;
    }

    for (int i = 0; i < arrayInt3.size(); i++) {
        std::cout << "输出arrayInt3[" << i << "]=" << arrayInt3[i] << std::endl;;
    }
 
    system("pause");
    return 0;
}

结果如下:
image.png

2)begin()的使用

 std::array<int, 5>::iterator arrayIter = arrayInt.begin();
    std::cout << "输出arrayInt begin:" << *arrayIter << std::endl;

结果如下:
image.png

3)rbegin()的使用

//rbegin()的使用
    std::array<int, 5>::reverse_iterator arrayRIter = arrayInt.rbegin();
    std::cout << "输出arrayInt rbegin:" << *arrayIter << std::endl;

结果如下:
image.png

4)size()的使用

 //size()的使用
    std::cout << "输出arrayInt size:" << arrayInt.size() << std::endl;

结果如下:
image.png

5)max_size()的使用

//max_size()的使用
    std::cout << "输出arrayInt max_size:" << arrayInt.max_size() << std::endl;

结果如下:
image.png

6)at()的使用

//at()的使用
    std::cout << "输出arrayInt at(3):" << arrayInt.at(3) << std::endl;
    try
    {
        std::cout << "输出arrayInt at(6):" << arrayInt.at(6) << std::endl;
    }
    catch (const std::exception&)
    {
        std::cout << "at(6)操作异常" << std::endl;
    }

结果如下:
image.png

7)data()的使用

 //data()的使用
    int *pData = arrayInt.data();
    for (int i = 0; i < arrayInt.size(); i++)
    {
        std::cout << "输出arrayInt[:" << i << "]=" << *pData++ << std::endl;
    }

结果如下:
image.png

8)fill()的使用

 //fill()的使用
    arrayInt.fill(8);
    for (int i = 0; i < arrayInt.size(); i++) {
        std::cout << "输出arrayInt[" << i << "]=" << arrayInt[i] << std::endl;
    }

结果如下:
image.png

9)swap的使用

 std::array<int, 5> arrayInt4;
    arrayInt.swap(arrayInt4);
    for (int i = 0; i < arrayInt4.size(); i++) {
        std::cout << "输出arrayInt4[" << i << "]=" << arrayInt4[i] << std::endl;
    }

结果如下:
image.png

10)crbegin()的使用

 std::array<int, 5>::const_reverse_iterator arrayRe = arrayInt.crbegin();
    std::cout << "输出arrayInt crbegin:" << *arrayRe << std::endl;

结果如下:
image.png

image.png

三、array随机访问迭代器

在 array 容器的模板类中,和随机访问迭代器相关的成员函数有:
begin()
end()
rbegin()
rend()
cbegin()
cend()
crbegin()
crend()
具体的功能如下:
image.png
根据它们的功能并结合实际场景的需要,这些成员函数通常是成对使用的,即 begin()/end()、rbegin()/rend()、cbegin()/cend()、crbegin()/crend() 各自成对搭配使用,其中 begin()/end() 和 cbegin()/cend()、rbegin()/rend() 和 crbegin()/crend() 的功能大致是相同的。
注意:
在使用反向迭代器进行 ++ 或 -- 运算时,++ 指的是迭代器向左移动一位,-- 指的是迭代器向右移动一位,即这两个运算符的功能也“互换”了,即反向迭代器以逆序的方式处理元素。

四、array容器访问元素的几种方式

1、容器名[]

类似于C++中访问数组元素的方式,需要注意的是:这种方式不会检查边界,所以可以存在索引越界的问题,因此不推荐使用这种方法。
重载[]时没有实现边界检查的原因:性能问题。每次访问元素,都去检查索引值,会产生很多开销。

2、at()

为了有效避免越界访问的问题,可使用array容器提供的at()成员函数
如设置索引位置4的值:

values.at (4) = values.at(3) + 2*values.at(1);

当传给at()的值是一盒越界值时,会抛出异常,为了避免程序崩溃,此处可以加异常机制处理。

3、data()

通过调用该函数可以得到指向容器首个元素的指针。通过该指针,我们可以获得容器中的各个元素。示例代码中有,这里不再说明

4、遍历容器

上面的方法是访问单个元素的,如果要访问容器中多个元素要怎么做呢?
首先可以通过size()获取容器的大小,在遍历容器取出元素即可

1 篇内容引用

小菜鸟一枚,望各位大佬不吝指教,用于记录学习

1 声望
0 粉丝
0 条评论
推荐阅读
C++ STL multiset容器
multiset 类模板提供的构造函数,和 set 类模板中提供创建 set 容器的构造函数,是完全相同的。因此创建set容器的方式适用于创建multiset容器。具体的方法参考set容器:[链接]

等待樱花盛开阅读 966

麒麟操作系统 (kylinos) 从入门到精通 - 研发环境 - 第二十一篇 C++/C语言开发环境搭建
类别:笔记本型号:中国长城 NF14C硬件平台:飞腾处理器(ArmV8 指令集)系统:银河麒麟操作系统 V10 SP1(2203) 关键词:信创,麒麟系统,linux,c++,c,内核飞腾,arm

码上世界1阅读 2.3k评论 1

封面图
万字避坑指南!C++的缺陷与思考(下)
导读 | 在万字避坑指南!C++的缺陷与思考(上)一文中,微信后台开发工程师胡博豪,分享了C++的发展历史、右值引用与移动语义、类型说明符等内容,深受广大开发者喜爱!此篇,我们邀请作者继续总结其在C++开发过...

腾讯云开发者4阅读 469评论 1

一种将函数模板定义和声明分开的方法
&emsp;&emsp;在 C++ 中为了操作简洁引入了函数模板。所谓的函数模板实际上是建立一个通用函数,其函数类型或形参类型不具体指定,用一个虚拟的类型来表达,这个通用函数就称为函数模板。

Sharemaker阅读 846

封面图
Workflow的JSON解析器
Workflow中有一个小而美的json-parser,一千行代码写得非常典雅精致。不仅可以学习到经典的C语言写法、递归解析的架构、与内核近似的编码风格、简洁的接口设计,而且也非常方便引入项目中作为轻量级的json解析器...

1412阅读 780

C发展史的特点与常见的C语言程序
1、1963年,剑桥人学将ALGOL 60语言发展成为CPL语言。2、1967年,朝侨大学的Martin Richards 对CPL语言进行了简化,产生了BCPL语言。3、1970年,美国贝尔实验室的Ken Thompson将BCPL中的精华提炼出来,并为它起了...

菜鸟明轩阅读 723

C语言中的4大基本数据类型
⭐基本数据类型 整型 int 字符型 char 实型(浮点型):单精度实型 float 双精度实型 double⭐构造类型数组类型结构类型 struct联合类型 union枚举类型 enum⭐指针类型⭐空类型 void

菜鸟明轩阅读 684

封面图

小菜鸟一枚,望各位大佬不吝指教,用于记录学习

1 声望
0 粉丝
宣传栏