std::array
What problem does this section solve?
C-style arrays (int arr[5]) have many drawbacks: they cannot be assigned directly, they decay into pointers when passed to functions (losing size information), and there is no bounds checking. Dynamic allocation (std::vector), however, is powerful but involves dynamically allocating memory, which comes with a small overhead.
std::array addresses the need for a compile-time sized, stack-allocated array that offers the same performance as a C array but with an STL container interface (including size(), iterators, and assignability), providing a safe alternative.
What is this feature?
std::array<T, N> is a container template in the STL that encapsulates a fixed-size array. Its size is determined at compile time and does not dynamically allocate memory (it resides on the stack), wrapping a C array while providing the standard interface of an STL container.
C++ standard version
C++11
Required header files
#include <array>
运行结果: 此代码块不含 main 函数,是语法、接口或分文件示例,不能独立运行,因此没有终端输出。
Basic Syntax
std::array<元素类型, 大小> 变量名; // 默认初始化(值未定义)
std::array<元素类型, 大小> 变量名 = {}; // 全部初始化为零
std::array<元素类型, 大小> 变量名 = {v1, v2, ...}; // 列表初始化
运行结果: 此代码块不含 main 函数,是语法、接口或分文件示例,不能独立运行,因此没有终端输出。
Common Usage
| Operation | Explanation |
|---|---|
a[i] | Random access (without bounds checking) |
a.at(i) | random access (with bounds checking) |
a.size() | Return element count (compile-time constant) |
a.empty() | Whether it is empty (always false) |
a.front() | Return the first element. |
a.back() | Return the last element |
a.fill(val) | Fill all elements with val |
a.data() | Return pointer to underlying C array |
Example code
Example 1: Create an array and access elements
#include <iostream>
#include <array>
using namespace std;
int main()
{
// 创建一个包含 5 个 int 的 array,并初始化
std::array<int, 5> arr = {10, 20, 30, 40, 50};
// 用下标访问
std::cout << "arr[0] = " << arr[0] << "\n";
std::cout << "arr[4] = " << arr[4] << "\n";
// 用 size() 获取大小
std::cout << "size = " << arr.size() << "\n";
return 0;
}
Results:
arr[0] = 10
arr[4] = 50
size = 5
Example 2: Based on Example 1, using at() for safe access and fill() for filling
#include <iostream>
#include <array>
using namespace std;
int main()
{
std::array<int, 5> arr = {10, 20, 30, 40, 50};
// 用 at() 安全访问
std::cout << "arr.at(2) = " << arr.at(2) << "\n";
// 用 fill() 将所有元素设为同一个值
arr.fill(99);
std::cout << "after fill: ";
for (int n : arr)
{
std::cout << n << " ";
}
std::cout << "\n";
return 0;
}
Results:
arr.at(2) = 30
after fill: 99 99 99 99 99
Example 3: Building on Example 2, comparing C arrays and std::array parameter passing
#include <iostream>
#include <array>
using namespace std;
// C 风格:数组退化为指针,丢失大小信息
void print_c_array(int* arr, int size)
{
std::cout << "C array: ";
for (int i = 0; i < size; ++i)
{
std::cout << arr[i] << " ";
}
std::cout << "\n";
}
// std::array:大小信息不丢失
void print_std_array(const std::array<int, 5>& arr)
{
std::cout << "std::array: ";
for (int n : arr)
{
std::cout << n << " ";
}
std::cout << "\n";
std::cout << "size from inside function = " << arr.size() << "\n";
}
int main()
{
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// C 风格:需要额外传大小
print_c_array(arr.data(), arr.size());
// std::array:自带大小信息
print_std_array(arr);
return 0;
}
Results:
C array: 1 2 3 4 5
std::array: 1 2 3 4 5
size from inside function = 5
runtime results
See the "running results" for each example above.
Key syntax explanation in the example
|Here is the translation of the provided Simplified Chinese Markdown fragment into natural American English, following all specified rules.
| Example | Discusses what | Newly emerged syntax | Why write it this way | Precautions |
|---|---|---|---|---|
| Example 1 | Create array and basic access | std::array<T, N>、size() | The array size is a compile-time constant, size() returns a fixed value. | The size must be a compile-time constant; variables cannot be passed. |
| Example 2 | at() safe access and fill() filling | at()、fill() | at() throws an exception when out of bounds; fill() convenient for batch assignment. | fill() Assign the same value to all elements |
| Example 3 | Comparing C arrays and array parameter passing | data()、const std::array<int,5>& | Size information is not lost when passing arrays as parameters. | The size of an array is part of its type, and different sizes are different types. |
The differences between array and vector become most evident in the following scenarios:
- When fixed-size storage is needed: If you know the exact number of elements at compile time and this size won't change,
arrayis more efficient. - When dynamic resizing is required: If the number of elements may change during runtime,
vectoris the clear choice. - In performance-sensitive contexts:
arrayavoids the overhead of heap allocation and dynamic resizing, making it faster in tight loops or embedded systems. - When passing data to low-level APIs:
arrayprovides a contiguous, fixed-size block of memory that aligns well with C-style functions.
If just storing 5 integers, array and vector seem to both work. However, within a project, the differences mainly lie in "whether the size is fixed" and "whether dynamic expansion is needed":
| Scene | Recommendation | Reason |
|---|---|---|
Three-axis IMU data {x, y, z} | std::array<double, 3> | The size is always 3, no expansion needed. |
Fixed-length PID parameters {kp, ki, kd} | std::array<double, 3> | The size is known at compile time, with clear semantics. |
| Reading a batch of sensor data at runtime. | std::vector<Point> | The number of points is only known at runtime. |
| User inputs any amount of data. | std::vector<T> | require dynamic growth for push_back |
array is more like "a fixed-size array with an STL interface," while vector is more like "a resizable array." Don't use array everywhere just because it's more lightweight: whenever the number of elements isn't known until runtime, you should use vector.
Example 4: Fixed three-axis data is better suited for array.
#include <array>
#include <iostream>
using namespace std;
// std::array 是固定长度数组,长度在编译期就确定。
double norm3(const std::array<double, 3>& v)
{
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}
int main()
{
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
std::array<double, 3> accel = {0.1, 0.2, 9.8};
std::cout << "accel size = " << accel.size() << "\n";
std::cout << "squared norm = " << norm3(accel) << "\n";
return 0;
}
Results:
accel size = 3
squared norm = 96.09
In this example, the three-axis data must be exactly 3 values. Using std::array<double, 3> allows this constraint to be written into the type; if std::array<double, 2> is mistakenly passed, it will result in a compile-time error.
Common Errors
Error 1: Specifying array size with a variable
int n = 5;
std::array<int, n> arr; // ❌ 编译错误!n 必须是编译期常量
运行结果: 此代码块不含 main 函数,是语法、接口或分文件示例,不能独立运行,因此没有终端输出。
The correct approach: use the constexpr constant, or alternatively switch to std::vector.
Error 2: Accessing before initialization
std::array<int, 5> arr; // 值未定义(栈上的垃圾值)
std::cout << arr[0]; // ❌ 未定义行为
运行结果: 此代码块不含 main 函数,是语法、接口或分文件示例,不能独立运行,因此没有终端输出。
Correct approach: Initialize with {} or use fill().
Error 3: Assigning between arrays of different sizes
std::array<int, 3> a = {1, 2, 3};
std::array<int, 5> b = a; // ❌ 编译错误!类型不同
运行结果: 此代码块不含 main 函数,是语法、接口或分文件示例,不能独立运行,因此没有终端输出。
The correct approach: std::array<int,3> and std::array<int,5> are of different types and cannot be assigned to each other.
使用建议
- 明确目标:在开始前确定您的具体需求,以便选择最合适的工具或教程。
- 充分利用资源:参考官方文档、教程和博客,这些资料能帮助您快速上手并解决问题。
- 实践应用:通过动手操作项目或编写代码来巩固学习成果,提升实际操作能力。
- 问题解决:遇到困难时,查阅参考资料或寻求社区支持,逐步培养独立解决问题的能力。
- 分享经验:完成项目后,可以撰写文章或博客分享心得,帮助其他学习者。
如果需要针对特定领域(如单片机、机器人或环境搭建)的进一步建议,请提供更多信息,我将为您细化内容。
- For sizes known at compile time, use an array:If the size is known at compile time, using
std::arrayis more lightweight thanstd::vector(without heap allocation). - Replacing C Arrays: Use
std::arraywheneverint arr[N]can be used. - Note the size when passing arguments: The size of
std::array<T, N>is part of its type, and the function signature must specify N. - Assignable: Unlike C arrays,
std::arraycan be assigned as a whole using=(of the same type).
Summary
std::array<T, N>encapsulates a fixed-size array, with its size determined at compile time.- Includes the standard interface of STL containers (
size(),at(), iterators, etc.). - Yes, you can assign the entire array, and when passing it to a function, it won’t decay into a pointer, so the size information is retained.
- Suitable for scenarios where the size is known at compile time, more lightweight than
vector.