C++11中std::array的使用

定义于头文件 <array>
template < class T,  std::size_t N  > struct array;

一种特殊情况是 array ( N == 0 )。该情况下, array.begin() == array.end() ,
并拥有某个唯一值。在零长 array 上调用 front() 或 back() 的效应是未定义的。

简单来说,std::array除了有传统数组支持随机访问、效率高、存储大小固定等特点外,还支持迭代器访问、获取容量、获得原始指针等高级功能。

std::array是在C++11中才引入的,与内置数组相比,array是一种更安全、更容易使用的数组类型。与内置数组类似,array对象的大小是固定的。因此,array不支持添加和删除元素以及改变容器大小的操作。

必须同时指定元素类型和大小。array不能被动态地扩展或压缩。

一个默认构造的array是非空的:它包含了与其大小一样多的元素。这些元素都被默认初始化。如果我们对array进行列表初始化,初始值的数目必须等于或小于array的大小。如果初始值数目小于array的大小,则它们被用来初始化array中靠前的元素,所有剩余元素都会进行值初始化。在这两种情况下,如果元素类型是一个类类型,那么该类必须有一个默认构造函数,以使值初始化能够进行。

        标准库中的顺序容器包括:

        (1)、vector:可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。

        (2)、deque:双端队列。支持快速随机访问。在头尾位置插入/删除速度很快。

        (3)、list:双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快。

        (4)、forward_list:单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快。

        (5)、array:固定大小数组。支持快速随机访问。不能添加或删除元素。

        (6)、string:与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快。

     forward_list和array是新C++标准增加的类型。forward_list的设计目标是达到与最好的手写的单向链表数据结构相当的性能。因此,forward_list没有size操作,因为保存或计算其大小就会比手写链表多出额外的开销。对其他容器而言,size保证是一个快速的常量时间的操作。

      选择容器的基本原则:

        (1)、除非你有很好的理由选择其他容器,否则应该使用vector;

        (2)、如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list或forward_list;

        (3)、如果程序要求随机访问元素,应使用vector或deque;

       (4)、如果程序要求在容器的中间插入或删除元素,应使用list或forward_list;

       (5)、如果程序需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用deque;

       (6)、如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素,则:首先,确定是否真的需要在容器中间位置添加元素。当处理输入数据时,通常可以很容器地向vector追加数据,然后再调用标准库的sort函数来重排容器中的元素,从而避免在中间位置添加元素。如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将list中的内容拷贝到一个vector中。

如果你不确定应该使用哪种容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下标操作,避免随机访问。这样,在必要时选择使用vector或list都很方便。

一般来说,每个容器都定义在一个头文件中,文件名与类型名相同。即,deque定义在头文件deque中,list定义在头文件list中,以此类推。容器均定义为模板类。

除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。适配器(adaptor)是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。

#include <iostream>
#include <array>
#include <tuple>
#include <string>
#include<string.h>

int test_array_3()
{
    typedef std::array<int, 4> Myarray;

    Myarray c0 = { 0, 1, 2, 3 };
    // display contents " 0 1 2 3"
    for (Myarray::const_iterator it = c0.begin();
         it != c0.end(); ++it)
        std::cout << " " << *it;

    return 0;
}

// default initialization (non-local = static storage):
std::array<int, 3> global; // zero-initialized: {0,0,0}

int test_array_1()
{
    {
        // default initialization (local = automatic storage):
        std::array<int, 3> first; // uninitialized:    {?,?,?}

        // initializer-list initializations:
        std::array<int, 3> second = { 10, 20 };// initialized as:   {10,20,0}
        std::array<int, 3> third = { 1, 2, 3 };// initialized as:   {1,2,3}

        // copy initialization:
        std::array<int, 3> fourth = third;     // copy:{1,2,3}
        for (auto x : fourth) std::cout << ' ' << x;
    }

    { // array::at: Returns a reference to the element at position n in the array
        std::array<int, 10> myarray;
        for (int i = 0; i < 10; i++) myarray.at(i) = i + 1;
    }

    { // array::back: Returns a reference to the last element in the array container.
      // array::front: Returns a reference to the first element in the array container.
        std::array<int, 3> myarray = { 5, 19, 77 };

        std::cout << myarray.front() << std::endl;   // 5
        std::cout << myarray.back() << std::endl;     // 77

        myarray.back() = 50;
        myarray.front() = 999;

        for (int& x : myarray) std::cout << ' ' << x; // 999 19 50
    }

    { // array::data: Returns a pointer to the first element in the array object.
        const char* cstr = "Test string";
        std::array<char, 12> charray;

        memcpy(charray.data(), cstr, 12);
    }

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

    { // array::fill: Sets val as the value for all the elements in the array object.
        std::array<int, 6> myarray;
        myarray.fill(5);
    }

    { // array::max_size: Returns the maximum number of elements that the array container can hold
        // array::size: Returns the number of elements in the array container.
        std::array<int, 10> myints;
        std::cout << "size of myints: " << myints.size() << '\n';
        std::cout << "max_size of myints: " << myints.max_size() << '\n';
        std::cout << "sizeof(myints): " << sizeof(myints) << std::endl;
    }

    { // array::operator[]: Returns a reference to the element at position n in the array container.
        std::array<int, 10> myarray;
        unsigned int i;

        // assign some values:
        for (i = 0; i < 10; i++) myarray[i] = i;
    }

    { // array::rbegin: Returns a reverse iterator pointing to the last element in the array container.
        // array::rend: Returns a reverse iterator pointing to the theoretical element preceding
        // the first element in the array (which is considered its reverse end).
        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';
    }

    { // array::swap: Exchanges the content of the array by the content of x,
        // which is another array object of the same type (including the same size).
        std::array<int, 5> first = { 10, 20, 30, 40, 50 };
        std::array<int, 5> second = { 11, 22, 33, 44, 55 };

        first.swap(second);
    }

    { // std::get: Returns a reference to the Ith element of array arr
        std::array<int, 3> myarray = { 10, 20, 30 };
        std::tuple_element<0, decltype(myarray)>::type myelement;  // int myelement

        myelement = std::get<2>(myarray);
        std::get<2>(myarray) = std::get<0>(myarray);
        std::get<0>(myarray) = myelement;
    }

    { // std::relational operators(array):
        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;
}

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值