C++ STL序列式容器之array

一、array概述

array 容器是 C++ 11 标准中新增的序列容器,简单地理解,它就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。在使用上,它比普通数组更安全,且效率并没有因此变差。

1、array容器创建对象的格式

array<T, N>  value; //创建array对象

注意事项:
1)、使用 array 容器类型时,需要在源文件中包含头文件 array;
2)、T 用于指明容器中存储的具体数据类型,N 用于指明容器的大小,需要注意的是,这里的 N 必须是常量,不能用变量表示

2、特性

1)、和常规数组没有太大的差别,不能增加或删除元素;
2)、模板实例的元素被内部存储在标准数组中;
3)、和标准数组相比,array 容器的额外幵销很小;
4)、array容器的两个优点:
–>如果使用 at()访问数据时,当用一个非法的索引访问数组元素时,能够被检测到,因为容器知道它有多少个元素;
–>数组容器可以作为参数传给函数,而不再需要单独去指定数组元素的个数

二、array容器的使用

1、array对象初始化的方式

1)、使用初始化列表{ }初始化

array<int, 10> value {}; //将所有的元素初始化为 0 或者和默认元素类型等效的值
array<int, 10> value {1, 2, 3, 4}; //列表中的 4 个值用于初始化前 4 个元素,其余的元素都将为 0

2)、调用数组对象的成员函数 fill()初始化

array<int, 10> value;
value.fill(3); //将所有元素都设为3

fill() 函数将所有元素都设为传入的实参值
程序示例:

#include <iostream>
#include <array>

using namespace std;

int main()
{
    array<int, 5> value1 {};
    cout << " 默认初始化:" << endl;
    for (auto a : value1)
        cout << "value = " << a << endl;
    cout << endl;

    array<int, 5> value2 {1, 2, 3};
    cout << " 部分初始化:" << endl;
    for (auto a : value2)
        cout << "value = " << a << endl;
    cout << endl;

    array<int, 5> value3;
    value3.fill(10);
    cout << "fill()初始化:" << endl;
    for (auto a : value3)
        cout << "value = " << a << endl;

    return 0;
}

结果:
在这里插入图片描述

3)、用函数模板 iota()以连续的递增值初始化一个数组容器,它定义在头文件 numeric 中

程序示例:

#include <iostream>
#include <array>
#include <numeric>

using namespace std;

int main()
{
    array<int, 5> myarray;
    iota(begin(myarray), end(myarray), 1); //从1开始递增

    for (auto a : myarray)
        cout << a << ' ';

    return 0;
}

运行结果:1 2 3 4 5

2、获取array元素的方式

可通过以下函数获取array容器的元素:
在这里插入图片描述
各个成员函数的用法及说明如下:

注:
1)、成员类型reference和const_reference是对数组元素的引用类型
2)、成员类型size_type是无符号整数类型size_t的别名

1、成员函数operator[]:
1)、函数原型:
reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
2)、参数:元素在数组中的位置,第一个元素的位置为0而不是1
3)、返回值:返回对数组容器中位置n处元素的引用,如果数组对象是const限定的,则该函数返回const_reference。否则,它返回一个reference
4)、异常安全:如果容器的大小大于n,则该函数从不抛出异常(无抛出保证)
5)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的。

程序示例:

// array::operator[]
#include <iostream>
#include <array>

using namespace std;

int main ()
{
    array<int, 10> myarray;

    // 初始化:
    for (int i = 0; i < 10; i++)
        myarray.at(i) = i + 1;

    // 打印:
    cout << "myarray contains:";
    for (int i = 0; i < 10; i++)
        cout << ' ' << myarray[i];
    cout << '\n';

    return 0;
}

运行结果:myarray contains: 1 2 3 4 5 6 7 8 9 10

2、成员函数 at():
1)、函数原型:
reference at ( size_type n );
const_reference at ( size_type n ) const;
2)、参数:元素在数组中的位置,第一个元素的位置为0而不是1
3)、返回值:返回数组中位置n处元素的引用,如果数组对象是const限定的,则该函数返回const_reference。否则,它返回一个reference
4)、异常安全:at()会进行下标越界的检查,当传给 at() 的索引是一个越界值时,这时会抛出 std::out_of_rang 异常;
5)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

// array::at()
#include <iostream>
#include <array>

using namespace std;

int main ()
{
    array<int, 10> myarray;

    // 初始化:
    for (int i = 0; i < 10; i++)
        myarray.at(i) = i + 1;

    // 打印:
    cout << "myarray contains:";
    for (int i = 0; i < 10; i++)
        cout << ' ' << myarray.at(i);
    cout << '\n';

    return 0;
}

运行结果:myarray contains: 1 2 3 4 5 6 7 8 9 10

3、成员函数front()
1)、函数原型:
reference front();
const_reference front() const;
2)、参数:无参数
3)、返回值:返回对数组容器中第一个元素的引用,如果数组对象是const限定的,则该函数返回const_reference。否则,它返回一个reference。
4)、异常安全:如果容器不为空,则该函数永远不会抛出异常(无抛出保证)。
否则,它将导致未定义的行为。
5)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的。

程序示例:

// array::front()
#include <iostream>
#include <array>

using namespace std;

int main()
{
    array<int, 3> myarray = {2, 16, 77};

    cout << "front is: " << myarray.front() << endl;   // 2
    cout << "back is: " << myarray.back() << endl;     // 77

    myarray.front() = 100;

    cout << "myarray now contains:";
    for ( int& x : myarray )
        cout << ' ' << x;
    cout << '\n';

    return 0;
}

运行结果:

front is: 2
back is: 77
myarray now contains: 100 16 77

4、成员函数back()
1)、函数原型:
reference back();
const_reference back() const;
2)、参数:无参数
3)、返回值:返回对数组容器中最后一个元素的引用,如果数组对象是const限定的,则该函数返回const_reference。否则,它返回一个reference。
4)、异常安全:如果容器不为空,则该函数永远不会抛出异常(无抛出保证)。
否则,它将导致未定义的行为。
5)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的。

程序示例同front()。

5、成员函数data()
1)、函数原型:
value_type* data() noexcept;
const value_type* data() const noexcept;
2)、参数:无参数
3)、返回值:返回指向数组对象中第一个元素的指针,如果数组对象是const限定的,则该函数返回的指针为 const value_type。否则,它返回一个指向value_type类型指针。
4)、异常安全:此成员函数不会抛出异常
5)、调用不会直接访问任何包含的元素,但是返回的指针可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

// array::data
#include <iostream>
#include <cstring>
#include <array>

int main ()
{
  const char* cstr = "Test string";
  std::array<char, 12> charray;

  std::memcpy(charray.data(), cstr, 12);

  std::cout << charray.data() << '\n';

  return 0;
}

运行结果:Test string

6、使用非成员函数 get() ,它能够获取到容器的第 n 个元素

#include <iostream>
#include <array>

using namespace std;

int main()
{
    array<int, 5> myarray {1, 2, 3};
    cout << get<2>(myarray) << '\n';

    return 0;
}

运行结果:3

3、array迭代器

迭代器的作用是遍历array数组类中的元素

迭代器函数:
在这里插入图片描述
各个成员函数的用法及说明如下:

正向迭代器begin()和end()

1、成员函数begin()
1)、函数原型:
iterator begin() noexcept;
const_iterator begin() const noexcept;
2)、参数:无参数
3)、返回值:返回指向数组容器中第一个元素的迭代器,如果数组对象是const限定的,则该函数返回const_iterator。否则,它返回一个iterator。
成员类型iterator和const_iterator是随机访问迭代器类型(分别指向元素和const元素)。
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

2、成员函数end()
1)、函数原型:
iterator end() noexcept;
const_iterator end() const noexcept;
2)、参数:无参数
3)、返回值:返回指向最后一个元素的下一个位置的随机访问迭代器,在零大小的数组中,此函数返回的结果与array :: begin相同。如果数组对象是const限定的,则该函数返回const_iterator。否则,它返回一个iterator
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

// array::begin() and end() example
#include <iostream>
#include <array>

int main ()
{
  std::array<int,5> myarray = { 5, 19, 77, 34, 99 };

  std::cout << "myarray contains:";
  for ( auto it = myarray.begin(); it != myarray.end(); ++it )
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

运行结果:myarray contains: 5 19 77 34 99

反向迭代器rbegin()和rend()

3、成员函数rbegin()
1)、函数原型:
reverse_iterator rbegin()noexcept;
const_reverse_iterator rbegin()const noexcept;
2)、参数:无参数
3)、返回值:返回指向容器中的最后一个元素的位置,如果数组对象是const限定的,则该函数返回const_iterator。否则,它返回一个iterator。
成员类型iterator和const_iterator是反向随机访问迭代器类型(分别指向元素和const元素)。
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

4、成员函数rend()
1)、函数原型:
reverse_iterator rend()noexcept;
const_reverse_iterator rend()const noexcept;
2)、参数:无参数
3)、返回值:返回指向数组中第一个元素的前一个位置,如果数组对象是const限定的,则该函数返回const_iterator。否则,它返回一个iterator。
成员类型iterator和const_iterator是反向随机访问迭代器类型(分别指向元素和const元素)。
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

// array::rbegin/rend
#include <iostream>
#include <array>

int main ()
{
  std::array<int,4> myarray = {4, 26, 80, 14} ;

  std::cout << "myarray contains:";
  for ( auto rit=myarray.rbegin() ; rit < myarray.rend(); ++rit )
    std::cout << ' ' << *rit;

  std::cout << '\n';

  return 0;
}

运行结果:myarray contains: 14 80 26 4

5、成员函数cbegin()
1)、函数原型:
const_iterator cbegin()const noexcept;
2)、参数:无参数
3)、返回值:返回指向const数组容器中第一个元素的位置
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问它们。同时访问或修改不同的元素是安全的

6、成员函数cend()
1)、函数原型:
const_iterator cend()const noexcept;
2)、参数:无参数
3)、返回值:返回指向const数组容器中最后一个元素的下一个位置
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问元素。同时访问或修改不同的元素是安全的

程序示例:

// array::cend example
#include <iostream>
#include <array>

int main ()
{
  std::array<int, 5> myarray = { 15, 720, 801, 1002, 3502 };

  std::cout << "myarray contains:";
  for ( auto it = myarray.cbegin(); it != myarray.cend(); ++it )
    std::cout << ' ' << *it;   // cannot modify *it

  std::cout << '\n';

  return 0;
}

运行结果:myarray contains: 15 720 801 1002 3502

7、成员函数rcbegin()
1)、函数原型:
const_reverse_iterator crbegin()const noexcept;
2)、参数:无参数
3)、返回值:返回指向数组容器中最后一个元素的const_reverse_iterator,类型const_reverse_iterator是指向const元素的反向随机访问迭代器类型
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问它们。同时访问或修改不同的元素是安全的

8、成员函数rcend()
1)、函数原型:
const_reverse_iterator crend()const noexcept;
2)、参数:无参数
3)、返回值:返回指向const数组容器中第一个元素的前一个位置,返回类型为const_reverse_iterator,类型const_reverse_iterator是指向const元素的反向随机访问迭代器类型
4)、异常安全:不会抛出异常。返回的迭代器的复制构造函数或者赋值运算也不会抛出
5)、不会访问容器中的元素,但是返回的迭代器可用于访问元素。同时访问或修改不同的元素是安全的

程序示例:

// array::crbegin/crend
#include <iostream>
#include <array>

int main ()
{
  std::array<int,6> myarray = {10, 20, 30, 40, 50, 60} ;

  std::cout << "myarray backwards:";
  for ( auto rit = myarray.crbegin() ; rit < myarray.crend(); ++rit )
    std::cout << ' ' << *rit;   // cannot modify *rit

  std::cout << '\n';

  return 0;
}

运行结果:myarray backwards: 60 50 40 30 20 10

4、获取array容器的容量

可通过以下函数获取容器的容量信息:
在这里插入图片描述

1、成员函数size()
1)、函数原型:
constexpr size_type size()noexcept;
2)、参数:无参数
3)、返回值:返回数组容器中的元素数,与运算符sizeof(以字节为单位返回大小)不同,该成员函数以元素数的形式返回数组的大小
4)、异常安全:不会抛出异常
5)、不会访问容器中的元素,同时访问或修改不同的元素是安全的

程序示例:

// array::size
#include <iostream>
#include <array>

int main ()
{
  std::array<int,5> myints;
  std::cout << "size of myints: " << myints.size() << std::endl;
  std::cout << "sizeof(myints): " << sizeof(myints) << std::endl;

  return 0;
}

运行结果:

size of myints: 5
sizeof(myints): 20

2、成员函数max_size()
1)、函数原型:
constexpr size_type max_size()noexcept;
2)、参数:无参数
3)、返回值:返回数组容器可以容纳的最大元素数
4)、异常安全:不会抛出异常
5)、不会访问容器中的元素,同时访问或修改不同的元素是安全的

程序示例:

// array::max_size
#include <iostream>
#include <array>

int main ()
{
  std::array<int, 10> myints;
  std::cout << "size of myints: " << myints.size() << '\n';
  std::cout << "max_size of myints: " << myints.max_size() << '\n';

  return 0;
}

运行结果:

size of myints: 10
max_size of myints: 10

3、成员函数empty()
1)、函数原型:
constexpr bool empty()noexcept;
2)、参数:无参数
3)、返回值:返回一个布尔值
4)、异常安全:不会抛出异常
5)、不会访问容器中的元素,同时访问或修改不同的元素是安全的

程序示例:

// array::empty
#include <iostream>
#include <array>

int main ()
{
  std::array<int,0> first;
  std::array<int,5> second;
  std::cout << "first " << (first.empty() ? "is empty" : "is not empty") << '\n';
  std::cout << "second " << (second.empty() ? "is empty" : "is not empty") << '\n';
  return 0;
}

运行结果:

first is empty
second is not empty

5、修改array容器的元素

在这里插入图片描述

1、成员函数fill()
1)、函数原型:
void fill (const value_type& val);
2)、参数:整型
3)、返回值:无
4)、异常安全:会抛出异常
5)、容器中所有元素的值被修改为传入的参数值

程序示例:

// array::fill example
#include <iostream>
#include <array>

int main () 
{
  std::array<int,6> myarray;

  myarray.fill(5);

  std::cout << "myarray contains:";
  for ( int& x : myarray) { std::cout << ' ' << x; }

  std::cout << '\n';

  return 0;
}

运行结果:

myarray contains: 5 5 5 5 5 5

2、成员函数swap()
1)、函数原型:

void swap (array& x) noexcept(noexcept(swap(declval<value_type&>(), declval<value_type&>())));

2)、参数:与X类型相同(包括相同大小)数组容器
3)、返回值:无
4)、异常安全:如果调用非成员方法swap在该类型的元素不会抛出异常,那么该方法也不会抛出异常。否则,容器保证在有效的状态。
5)、参数容器和X均被修改。调用可访问两个容器中的所有元素

程序示例:

// array::fill example
#include <iostream>
#include <array>

int main () 
{
  std::array<int,6> myarray;

  myarray.fill(5);

  std::cout << "myarray contains:";
  for ( int& x : myarray) { std::cout << ' ' << x; }

  std::cout << '\n';

  return 0;
}

运行结果:

first: 11 22 33 44 55
second: 10 20 30 40 50

6、关系运算符

//(1)	
template <class T, size_T N>
  bool operator== ( const array<T,N>& lhs, const array<T,N>& rhs );
//(2)	
template <class T, size_T N>
  bool operator!= ( const array<T,N>& lhs, const array<T,N>& rhs );
//(3)	
template <class T, size_T N>
  bool operator<  ( const array<T,N>& lhs, const array<T,N>& rhs );
//(4)	
template <class T, size_T N>
  bool operator<= ( const array<T,N>& lhs, const array<T,N>& rhs );
//(5)	
template <class T, size_T N>
  bool operator>  ( const array<T,N>& lhs, const array<T,N>& rhs );
//(6)	
template <class T, size_T N>
  bool operator>= ( const array<T,N>& lhs, const array<T,N>& rhs );

程序示例:

// array comparisons
#include <iostream>
#include <array>

int main ()
{
  std::array<int,5> a = {10, 20, 30, 40, 50};
  std::array<int,5> b = {10, 20, 30, 40, 50};
  std::array<int,5> c = {50, 40, 30, 20, 10};

  if (a==b) std::cout << "a and b are equal\n";
  if (b!=c) std::cout << "b and c are not equal\n";
  if (b<c) std::cout << "b is less than c\n";
  if (c>b) std::cout << "c is greater than b\n";
  if (a<=b) std::cout << "a is less than or equal to b\n";
  if (a>=b) std::cout << "a is greater than or equal to b\n";

  return 0;
}

运行结果:

a and b are equal
b and c are not equal
b is less than c
c is greater than b
a is less than or equal to b
a is greater than or equal to b

参考:
1、C++ STL容器参考手册
2、C语言中文网

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值