【C++】C++11的std::array的詳細剖析

當學習C++的時候,數組是最基本的結構之一,通常通過以下的方式來定義:

int a[5];
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之前,需要包含頭文件:

# include <array>

定義array時,需要指定其數據類型和大小,兩者不可或缺。同時,array的大小不能使用變量來指定,但對於內置數組來說,是可以使用變量來指定數組大小的

定義array時,可以使用{}來直接初始化,也可以使用另外的array來構造,但不可以使用內置數組來構造
例如:

# include <iostream>
# include <array>

int main(int argc, char const *argv[])
{
  std::array<int, 5> a0 = {0, 1, 2, 3, 4};          //正確
  std::array<int, 5> a1 = a0;                       //正確
  int m = 5;
  int b[m];                                 //正確,內置數組
  std::array<int, 5> a2;                    //正確
  std::array<int, m> a3;                    //錯誤,array不可以用變量指定
  std::array<int, 5> a4 = b;                //錯誤,array不可以用數組指定

  return 0;
}

如果使用gcc來進行編譯,需要指定c++11標準

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

元素訪問

std::array提供了[]atfrontbackdata的方式來進行元素:

訪問方式 含義
at 訪問指定的元素,同時進行越界檢查
[] 訪問指定的元素
front 訪問第一個元素
back 訪問最後一個元素
data 返回指向內存中數組第一個元素的指針

和一般的容器一樣,array還提供了迭代器的方式進行元素遍歷和訪問:

迭代器 含義
begin 返回指向容器第一個元素的迭代器
end 返回指向容器尾端的迭代器
rbegin 返回指向容器最後元素的逆向迭代器
rend 返回指向前端的逆向迭代器

例如:

# include <iostream>
# include <array>

int main(int argc, char const *argv[])
{
  std::array<int, 5> a = {0, 1, 2, 3, 4};
  std::cout << a.front() << " " << a.at(1) << " " << a[2] << " " << *(a.data() + 3) << " " << a.back() << std::endl;

  std::array<int, 5>::iterator iter;
  for (iter = a.begin(); iter != a.end(); ++iter)
    std::cout << *iter << " ";
  std::cout << std::endl;

  std::array<int, 5>::reverse_iterator riter;
  for (riter = a.rbegin(); riter != a.rend(); ++riter)
    std::cout << *riter << " ";
  std::cout << std::endl;

  return 0;
}

運行這段代碼,輸出爲:

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

其他函數

array支持其它一些函數:

函數 含義
empty 檢查容器是否爲空
size 返回容納的元素數
max_size 返回可容納的最大元素數
fill 以指定值填充容器
swap 交換內容

例如:

#include <iostream>
#include <algorithm>
#include <array>

int main()
{
  std::array<int, 5> a1 = {4, 0, 2, 1, 3};
  std::array<int, 5> a2;

  std::sort(a1.begin(), a1.end());                  //排序函數
  for(int a: a1)
    std::cout << a << ' ';
  std::cout << std::endl;

  std::reverse(a1.begin(), a1.end());                           //反轉a1
  for (std::array<int, 5>::iterator iter = a1.begin(); iter != a1.end(); ++iter)
    std::cout << *iter << " ";
  std::cout << std::endl;

  std::reverse_copy(a1.begin(), a1.end(), a2.begin());          //反轉a1的內容拷貝到a2
  for (int i = 0; i < a2.size(); ++i)
    std::cout << a2[i] << " ";
  std::cout << std::endl;
}

運行這段代碼,輸出爲:

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

需要注意的是,std::reversestd::reverse_copy的區別,前者反轉本身,後者反轉本身的內容拷貝到另一個容器中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章