博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ STL序列式容器之array
阅读量:294 次
发布时间:2019-03-01

本文共 12427 字,大约阅读时间需要 41 分钟。

C++ STL序列式容器之array

一、array概述

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

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

array
value; //创建array对象

注意事项:

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

2、特性

1)、和常规数组没有太大的差别,不能增加或删除元素;

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

二、array容器的使用

1、array对象初始化的方式

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

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

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

array
value;value.fill(3); //将所有元素都设为3

fill() 函数将所有元素都设为传入的实参值

程序示例:

#include 
#include
using namespace std;int main(){
array
value1 {
}; cout << " 默认初始化:" << endl; for (auto a : value1) cout << "value = " << a << endl; cout << endl; array
value2 {
1, 2, 3}; cout << " 部分初始化:" << endl; for (auto a : value2) cout << "value = " << a << endl; cout << endl; array
value3; value3.fill(10); cout << "fill()初始化:" << endl; for (auto a : value3) cout << "value = " << a << endl; return 0;}

结果:

在这里插入图片描述

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

程序示例:

#include 
#include
#include
using namespace std;int main(){
array
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 
#include
using namespace std;int main (){
array
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 
#include
using namespace std;int main (){
array
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 
#include
using namespace std;int main(){
array
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: 2back is: 77myarray 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 
#include
#include
int main (){
const char* cstr = "Test string"; std::array
charray; std::memcpy(charray.data(), cstr, 12); std::cout << charray.data() << '\n'; return 0;}

运行结果:Test string

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

#include 
#include
using namespace std;int main(){
array
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 
#include
int main (){
std::array
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 
#include
int main (){
std::array
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 
#include
int main (){
std::array
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 
#include
int main (){
std::array
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 
#include
int main (){
std::array
myints; std::cout << "size of myints: " << myints.size() << std::endl; std::cout << "sizeof(myints): " << sizeof(myints) << std::endl; return 0;}

运行结果:

size of myints: 5sizeof(myints): 20

2、成员函数max_size()

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

程序示例:

// array::max_size#include 
#include
int main (){
std::array
myints; std::cout << "size of myints: " << myints.size() << '\n'; std::cout << "max_size of myints: " << myints.max_size() << '\n'; return 0;}

运行结果:

size of myints: 10max_size of myints: 10

3、成员函数empty()

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

程序示例:

// array::empty#include 
#include
int main (){
std::array
first; std::array
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 emptysecond is not empty

5、修改array容器的元素

在这里插入图片描述

1、成员函数fill()

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

程序示例:

// array::fill example#include 
#include
int main () {
std::array
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
(), declval
())));

2)、参数:与X类型相同(包括相同大小)数组容器

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

程序示例:

// array::fill example#include 
#include
int main () {
std::array
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 55second: 10 20 30 40 50

6、关系运算符

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

程序示例:

// array comparisons#include 
#include
int main (){
std::array
a = {
10, 20, 30, 40, 50}; std::array
b = {
10, 20, 30, 40, 50}; std::array
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
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 equalb and c are not equalb is less than cc is greater than ba is less than or equal to ba is greater than or equal to b

参考:

1、
2、

转载地址:http://zpco.baihongyu.com/

你可能感兴趣的文章