C++ STL序列式容器之array

超、凢脫俗 2023-07-20 05:40 135阅读 0赞

C++ STL序列式容器之array

  • 一、array概述
    • 1、array容器创建对象的格式
    • 2、特性
  • 二、array容器的使用
    • 1、array对象初始化的方式
    • 2、获取array元素的方式
    • 3、array迭代器
    • 4、获取array容器的容量
    • 5、修改array容器的元素
    • 6、关系运算符

一、array概述

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

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

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

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

2、特性

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

二、array容器的使用

1、array对象初始化的方式

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

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

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

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

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

  1. #include <iostream>
  2. #include <array>
  3. using namespace std;
  4. int main()
  5. {
  6. array<int, 5> value1 { };
  7. cout << " 默认初始化:" << endl;
  8. for (auto a : value1)
  9. cout << "value = " << a << endl;
  10. cout << endl;
  11. array<int, 5> value2 { 1, 2, 3};
  12. cout << " 部分初始化:" << endl;
  13. for (auto a : value2)
  14. cout << "value = " << a << endl;
  15. cout << endl;
  16. array<int, 5> value3;
  17. value3.fill(10);
  18. cout << "fill()初始化:" << endl;
  19. for (auto a : value3)
  20. cout << "value = " << a << endl;
  21. return 0;
  22. }

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

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

程序示例:

  1. #include <iostream>
  2. #include <array>
  3. #include <numeric>
  4. using namespace std;
  5. int main()
  6. {
  7. array<int, 5> myarray;
  8. iota(begin(myarray), end(myarray), 1); //从1开始递增
  9. for (auto a : myarray)
  10. cout << a << ' ';
  11. return 0;
  12. }

运行结果: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)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的。

程序示例:

  1. // array::operator[]
  2. #include <iostream>
  3. #include <array>
  4. using namespace std;
  5. int main ()
  6. {
  7. array<int, 10> myarray;
  8. // 初始化:
  9. for (int i = 0; i < 10; i++)
  10. myarray.at(i) = i + 1;
  11. // 打印:
  12. cout << "myarray contains:";
  13. for (int i = 0; i < 10; i++)
  14. cout << ' ' << myarray[i];
  15. cout << '\n';
  16. return 0;
  17. }

运行结果: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)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::at()
  2. #include <iostream>
  3. #include <array>
  4. using namespace std;
  5. int main ()
  6. {
  7. array<int, 10> myarray;
  8. // 初始化:
  9. for (int i = 0; i < 10; i++)
  10. myarray.at(i) = i + 1;
  11. // 打印:
  12. cout << "myarray contains:";
  13. for (int i = 0; i < 10; i++)
  14. cout << ' ' << myarray.at(i);
  15. cout << '\n';
  16. return 0;
  17. }

运行结果: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)、返回的引用可用于访问或修改元素。同时访问或修改不同的元素是安全的。

程序示例:

  1. // array::front()
  2. #include <iostream>
  3. #include <array>
  4. using namespace std;
  5. int main()
  6. {
  7. array<int, 3> myarray = { 2, 16, 77};
  8. cout << "front is: " << myarray.front() << endl; // 2
  9. cout << "back is: " << myarray.back() << endl; // 77
  10. myarray.front() = 100;
  11. cout << "myarray now contains:";
  12. for ( int& x : myarray )
  13. cout << ' ' << x;
  14. cout << '\n';
  15. return 0;
  16. }

运行结果:

  1. front is: 2
  2. back is: 77
  3. 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)、调用不会直接访问任何包含的元素,但是返回的指针可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::data
  2. #include <iostream>
  3. #include <cstring>
  4. #include <array>
  5. int main ()
  6. {
  7. const char* cstr = "Test string";
  8. std::array<char, 12> charray;
  9. std::memcpy(charray.data(), cstr, 12);
  10. std::cout << charray.data() << '\n';
  11. return 0;
  12. }

运行结果:Test string

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

  1. #include <iostream>
  2. #include <array>
  3. using namespace std;
  4. int main()
  5. {
  6. array<int, 5> myarray { 1, 2, 3};
  7. cout << get<2>(myarray) << '\n';
  8. return 0;
  9. }

运行结果: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)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::begin() and end() example
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,5> myarray = { 5, 19, 77, 34, 99 };
  7. std::cout << "myarray contains:";
  8. for ( auto it = myarray.begin(); it != myarray.end(); ++it )
  9. std::cout << ' ' << *it;
  10. std::cout << '\n';
  11. return 0;
  12. }

运行结果: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)、不会访问容器中的元素,但是返回的迭代器可用于访问或修改元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::rbegin/rend
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,4> myarray = { 4, 26, 80, 14} ;
  7. std::cout << "myarray contains:";
  8. for ( auto rit=myarray.rbegin() ; rit < myarray.rend(); ++rit )
  9. std::cout << ' ' << *rit;
  10. std::cout << '\n';
  11. return 0;
  12. }

运行结果: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)、不会访问容器中的元素,但是返回的迭代器可用于访问元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::cend example
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int, 5> myarray = { 15, 720, 801, 1002, 3502 };
  7. std::cout << "myarray contains:";
  8. for ( auto it = myarray.cbegin(); it != myarray.cend(); ++it )
  9. std::cout << ' ' << *it; // cannot modify *it
  10. std::cout << '\n';
  11. return 0;
  12. }

运行结果: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)、不会访问容器中的元素,但是返回的迭代器可用于访问元素。同时访问或修改不同的元素是安全的

程序示例:

  1. // array::crbegin/crend
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,6> myarray = { 10, 20, 30, 40, 50, 60} ;
  7. std::cout << "myarray backwards:";
  8. for ( auto rit = myarray.crbegin() ; rit < myarray.crend(); ++rit )
  9. std::cout << ' ' << *rit; // cannot modify *rit
  10. std::cout << '\n';
  11. return 0;
  12. }

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

4、获取array容器的容量

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

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

程序示例:

  1. // array::size
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,5> myints;
  7. std::cout << "size of myints: " << myints.size() << std::endl;
  8. std::cout << "sizeof(myints): " << sizeof(myints) << std::endl;
  9. return 0;
  10. }

运行结果:

  1. size of myints: 5
  2. sizeof(myints): 20

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

程序示例:

  1. // array::max_size
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int, 10> myints;
  7. std::cout << "size of myints: " << myints.size() << '\n';
  8. std::cout << "max_size of myints: " << myints.max_size() << '\n';
  9. return 0;
  10. }

运行结果:

  1. size of myints: 10
  2. max_size of myints: 10

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

程序示例:

  1. // array::empty
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,0> first;
  7. std::array<int,5> second;
  8. std::cout << "first " << (first.empty() ? "is empty" : "is not empty") << '\n';
  9. std::cout << "second " << (second.empty() ? "is empty" : "is not empty") << '\n';
  10. return 0;
  11. }

运行结果:

  1. first is empty
  2. second is not empty

5、修改array容器的元素

在这里插入图片描述

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

程序示例:

  1. // array::fill example
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,6> myarray;
  7. myarray.fill(5);
  8. std::cout << "myarray contains:";
  9. for ( int& x : myarray) { std::cout << ' ' << x; }
  10. std::cout << '\n';
  11. return 0;
  12. }

运行结果:

  1. myarray contains: 5 5 5 5 5 5

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

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

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

程序示例:

  1. // array::fill example
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,6> myarray;
  7. myarray.fill(5);
  8. std::cout << "myarray contains:";
  9. for ( int& x : myarray) { std::cout << ' ' << x; }
  10. std::cout << '\n';
  11. return 0;
  12. }

运行结果:

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

6、关系运算符

  1. //(1)
  2. template <class T, size_T N>
  3. bool operator== ( const array<T,N>& lhs, const array<T,N>& rhs );
  4. //(2)
  5. template <class T, size_T N>
  6. bool operator!= ( const array<T,N>& lhs, const array<T,N>& rhs );
  7. //(3)
  8. template <class T, size_T N>
  9. bool operator< ( const array<T,N>& lhs, const array<T,N>& rhs );
  10. //(4)
  11. template <class T, size_T N>
  12. bool operator<= ( const array<T,N>& lhs, const array<T,N>& rhs );
  13. //(5)
  14. template <class T, size_T N>
  15. bool operator> ( const array<T,N>& lhs, const array<T,N>& rhs );
  16. //(6)
  17. template <class T, size_T N>
  18. bool operator>= ( const array<T,N>& lhs, const array<T,N>& rhs );

程序示例:

  1. // array comparisons
  2. #include <iostream>
  3. #include <array>
  4. int main ()
  5. {
  6. std::array<int,5> a = { 10, 20, 30, 40, 50};
  7. std::array<int,5> b = { 10, 20, 30, 40, 50};
  8. std::array<int,5> c = { 50, 40, 30, 20, 10};
  9. if (a==b) std::cout << "a and b are equal\n";
  10. if (b!=c) std::cout << "b and c are not equal\n";
  11. if (b<c) std::cout << "b is less than c\n";
  12. if (c>b) std::cout << "c is greater than b\n";
  13. if (a<=b) std::cout << "a is less than or equal to b\n";
  14. if (a>=b) std::cout << "a is greater than or equal to b\n";
  15. return 0;
  16. }

运行结果:

  1. a and b are equal
  2. b and c are not equal
  3. b is less than c
  4. c is greater than b
  5. a is less than or equal to b
  6. a is greater than or equal to b

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

发表评论

表情:
评论列表 (有 0 条评论,135人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++ STL序列容器概述

    声明:该文章内容为整理笔记内容,内容来源见参考。 C++ STL之序列式容器概述 一、什么是序列式容器 二、序列式容器的分类 三、序列式容器之间

    相关 c++ stl关联容器 set

    关联式容器 1.什么是关联式容器 关联式容器依据特定的排序法则,自动对容器内的数据元素进行排序。排序的准则是以函数的形式呈现出来的,用来比较数据元素的值(value)或者键