一、前言

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 声望0 粉丝

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