【C++】C++11的std::array的详细剖析

雨点打透心脏的1/2处 2023-06-11 06:26 89阅读 0赞

当学习C++的时候,数组是最基本的结构之一,通常通过以下的方式来定义:

  1. int a[5];
  2. int *b = new int[5];

上面一句是在栈上定义了一个长度为5的数组,下面一句是在堆上定义了一个长度为5的数组,并用一个指针指向它。

C++11中,引入了一种新的数组定义方式std::array

本文实例源码github地址:https://github.com/yngzMiao/yngzmiao-blogs/tree/master/2019Q4/20191031。

std::array的特性

std::array是具有固定大小的数组。因此,它并不支持添加或删除元素等改变大小的操作。也就是说,当定义一个array时,除了指定元素类型,还要指定容器大小

既然有了内置的数组,为什么还要引入array呢?

内置的数组有很多麻烦的地方,比如无法直接对象赋值,无法直接拷贝等等,同时内置的数组又有很多比较难理解的地方,比如数组名是数组的起始地址等等。相比较于如vector等容器的操作,内置数组确实有一些不方便的地方。因此,C++11就引入array容器来代替内置数组。

简单来说,std::array除了有内置数组支持随机访问、效率高、存储大小固定等特点外,还支持迭代器访问、获取容量、获得原始指针等高级功能。而且它还不会退化成指针给开发人员造成困惑

std::array的使用

定义

使用array之前,需要包含头文件:

  1. # include <array>

定义array时,需要指定其数据类型和大小,两者不可或缺。同时,array的大小不能使用变量来指定,但对于内置数组来说,是可以使用变量来指定数组大小的

定义array时,可以使用{}来直接初始化,也可以使用另外的array来构造,但不可以使用内置数组来构造
例如:

  1. # include <iostream>
  2. # include <array>
  3. int main(int argc, char const *argv[])
  4. {
  5. std::array<int, 5> a0 = { 0, 1, 2, 3, 4}; //正确
  6. std::array<int, 5> a1 = a0; //正确
  7. int m = 5;
  8. int b[m]; //正确,内置数组
  9. std::array<int, 5> a2; //正确
  10. std::array<int, m> a3; //错误,array不可以用变量指定
  11. std::array<int, 5> a4 = b; //错误,array不可以用数组指定
  12. return 0;
  13. }

如果使用gcc来进行编译,需要指定c++11标准

  1. g++ test.cpp -o test -std=c++11
  2. ./test

元素访问

std::array提供了[]atfrontbackdata的方式来进行元素:






























访问方式 含义
at 访问指定的元素,同时进行越界检查
[] 访问指定的元素
front 访问第一个元素
back 访问最后一个元素
data 返回指向内存中数组第一个元素的指针

和一般的容器一样,array还提供了迭代器的方式进行元素遍历和访问:


























迭代器 含义
begin 返回指向容器第一个元素的迭代器
end 返回指向容器尾端的迭代器
rbegin 返回指向容器最后元素的逆向迭代器
rend 返回指向前端的逆向迭代器

例如:

  1. # include <iostream>
  2. # include <array>
  3. int main(int argc, char const *argv[])
  4. {
  5. std::array<int, 5> a = { 0, 1, 2, 3, 4};
  6. std::cout << a.front() << " " << a.at(1) << " " << a[2] << " " << *(a.data() + 3) << " " << a.back() << std::endl;
  7. std::array<int, 5>::iterator iter;
  8. for (iter = a.begin(); iter != a.end(); ++iter)
  9. std::cout << *iter << " ";
  10. std::cout << std::endl;
  11. std::array<int, 5>::reverse_iterator riter;
  12. for (riter = a.rbegin(); riter != a.rend(); ++riter)
  13. std::cout << *riter << " ";
  14. std::cout << std::endl;
  15. return 0;
  16. }

运行这段代码,输出为:

  1. yngzmiao@yngzmiao-virtual-machine:~/test$ g++ test.cpp -o test -std=c++11
  2. yngzmiao@yngzmiao-virtual-machine:~/test$ ./test
  3. 0 1 2 3 4
  4. 0 1 2 3 4
  5. 4 3 2 1 0

其他函数

array支持其它一些函数:






























函数 含义
empty 检查容器是否为空
size 返回容纳的元素数
max_size 返回可容纳的最大元素数
fill 以指定值填充容器
swap 交换内容

例如:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <array>
  4. int main()
  5. {
  6. std::array<int, 5> a1 = { 4, 0, 2, 1, 3};
  7. std::array<int, 5> a2;
  8. std::sort(a1.begin(), a1.end()); //排序函数
  9. for(int a: a1)
  10. std::cout << a << ' ';
  11. std::cout << std::endl;
  12. std::reverse(a1.begin(), a1.end()); //反转a1
  13. for (std::array<int, 5>::iterator iter = a1.begin(); iter != a1.end(); ++iter)
  14. std::cout << *iter << " ";
  15. std::cout << std::endl;
  16. std::reverse_copy(a1.begin(), a1.end(), a2.begin()); //反转a1的内容拷贝到a2
  17. for (int i = 0; i < a2.size(); ++i)
  18. std::cout << a2[i] << " ";
  19. std::cout << std::endl;
  20. }

运行这段代码,输出为:

  1. yngzmiao@yngzmiao-virtual-machine:~/test$ g++ test.cpp -o test -std=c++11
  2. yngzmiao@yngzmiao-virtual-machine:~/test$ ./test
  3. 0 1 2 3 4
  4. 4 3 2 1 0
  5. 0 1 2 3 4

需要注意的是,std::reversestd::reverse_copy的区别,前者反转本身,后者反转本身的内容拷贝到另一个容器中

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly95bmd6bWlhby5ibG9nLmNzZG4ubmV0_size_16_color_FFFFFF_t_70

发表评论

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

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

相关阅读

    相关 CCS6.2超详细使用方法

    CCS6.2超详细使用方法   本文介绍了如何安装CCS6.2、一步一步的建立工程、以及建立工程以后编译、调试、如何方便快捷有效率的使用CCS6.2。   一、