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>
Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.
Basic Syntax
std::array<元素类型, 大小> 变量名; // 默认初始化(值未定义)
std::array<元素类型, 大小> 变量名 = {}; // 全部初始化为零
std::array<元素类型, 大小> 变量名 = {v1, v2, ...}; // 列表初始化
Run/Observation Results: This is a syntax fragment, focus on the writing style; run it after completing the context.
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>
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>
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>
// 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>
// 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 必须是编译期常量
Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.
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]; // ❌ 未定义行为
Running/Observation Results: After running, the corresponding content will be printed according to the output statements. The variable values can be inferred based on the order of initialization, assignment, and function calls.
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; // ❌ 编译错误!类型不同
Running/Observing Results: This is a syntax or interface example, focus on the writing style; run and verify after incorporating it into a complete program.
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.