Arrays
2 min read
Arrays
An array stores a fixed number of elements of the same type in contiguous memory. C++ has C-style arrays (inherited from C) and the safer std::array from the standard library.
C-style arrays
#include <iostream>
int main() {
int scores[5] = {88, 72, 95, 61, 83};
for (int i = 0; i < 5; i++) {
std::cout << scores[i] << " ";
}
std::cout << "\n";
}
C-style arrays have two serious limitations: they do not know their own size at runtime, and they perform no bounds checking. scores[10] compiles without a warning and produces undefined behavior at runtime.
std::array
std::array<T, N> wraps a C-style array with a safe, standard-library interface. The size N is a compile-time constant:
#include <iostream>
#include <array>
#include <algorithm>
int main() {
std::array<int, 5> scores = {88, 72, 95, 61, 83};
std::cout << "Size: " << scores.size() << "\n"; // 5
// Range-based for
for (int s : scores) std::cout << s << " ";
std::cout << "\n";
// Sorted copy
std::array<int, 5> sorted = scores;
std::sort(sorted.begin(), sorted.end());
for (int s : sorted) std::cout << s << " ";
std::cout << "\n"; // 61 72 83 88 95
// Bounds-checked access
std::cout << scores.at(2) << "\n"; // 95
// scores.at(10); // throws std::out_of_range
}
std::array works with all standard algorithms, supports structured bindings, and can be passed to functions without decaying to a pointer.
Multidimensional arrays
#include <iostream>
#include <array>
int main() {
// C-style 2D array
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
std::cout << matrix[r][c] << " ";
}
std::cout << "\n";
}
// std::array of std::array
std::array<std::array<int, 3>, 3> grid = {{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}};
std::cout << grid[1][2] << "\n"; // 6
}
Passing arrays to functions
C-style arrays decay to a pointer when passed to a function, losing their size:
void process(int* arr, int size) { /* must pass size separately */ }
std::array passes cleanly by reference and retains its size:
void process(const std::array<int, 5>& arr) {
std::cout << arr.size() << "\n"; // still 5
}
For functions that work with any array size, use a template:
template <std::size_t N>
void process(const std::array<int, N>& arr) {
for (int x : arr) std::cout << x << " ";
}
When to use which
| Situation | Use |
|---|---|
| Fixed size, modern code | std::array<T, N> |
| Fixed size, interfacing with C APIs | C-style array |
| Variable size | std::vector<T> |
| Non-owning view of any array | std::span<T> (C++20) |
Learn modern C++ through working code. Each chapter introduces one concept — variables, functions, classes, templates, smart pointers, concurrency — with a clear example, a line-by-line explanation, and notes on how it applies in real programs.
View book →