array是容器类,相比于内置数组,array有以下优势:
- 不会退化为指针
- 通过变量名知道数组大小 sizeof(arr) / sizeof(arr[0])
- 可以自动类型推导(auto)
- 可以相互赋值 (arr1 = arr2)
头文件 array
名称空间 std
#include <array>
using std::array;
初始化
array a1<int, 3> = {1, 2, 4}; //使用了列表初始化
array a2<int, 3> {1, 2, 4};
array a3 {1, 2, 4}; // c++17, 模板类型自动推导(-std=c++17)
const int m = 5;
int b[m];
array<int, 5> a2;
array<int, m> a3;
array<int, 5> a4 = b; //错误,array不可以用数组指定
注意:大小必须指定。(与vector的【变长】不同)
成员函数
成员函数 | 使用示例 | 解释 |
---|---|---|
at | arr.at(1) = 88; | 返回位于指定位置 pos 的元素的引用,有边界检查。若 pos 不在容器范围内,则抛出 std::out_of_range 类型的异常。 |
operator[] | arr[0] = 1; | 返回位于指定位置 pos 的元素的引用。不进行边界检查。不同于 std::map::operator[],此运算符决不向容器插入新元素。通过此运算符访问不存在的元素是未定义行为。 |
data | pointer_func(container.data(), container.size());// container.data() 优于 &container[0] | 返回指向作为元素存储工作的底层数组的指针。返回的指针使得范围 [data(), data() + size()) 始终是有效范围,即使容器为空(此时 data() 不可解引用)。如果 size() 是 0,那么 data() 有可能会也有可能不会返回空指针。 |
front | arr.front() | 返回到容器首元素的引用。在空容器上对 front 的调用是未定义的。对于容器 c,表达式 c.front() 等价于 *c.begin()。 |
size | arr.size() | 返回容器中的元素数,即 std::distance(begin(), end())。 |
max_size | arr.max_size() | 为 size() 所返回的值 |
empty | arr.empty() | 检查容器是否无元素,即是否 begin() == end()。 |
fill | arr.fill({0xE2, 0x96, 0x84, 0xE2, 0x96, 0x80}); | 将定值 value 赋给容器中的所有元素。algorithm中的 std::fill(nums.begin(), nums.end(), ‘a’);似乎更好用 |
swap | arr1.swap(arr2); | 将容器内容与 other 的内容交换。不会导致迭代器和引用关联到别的容器。 |
思考题
void f(array<int, 3> arr)
{
for (int i : arr)
cout << i << endl;
return;
}
int main()
{
array arr{ 1, 2, 4 };
f(arr);
return 0;
}
必须在第一行写明array的大小吗?有没有不用写大小的写法?
答案
#include <iostream>
#include <array>
using namespace std;
template <size_t N> // important
void f(array<int, N> arr)
{
for (int i : arr)
cout << i << endl;
return;
}
int main()
{
array arr{ 1, 2, 4 };
f(arr);
return 0;
}
参考:https://zh.cppreference.com/w/cpp/container/array