C++ course menu
C++ Arrays: C-Style Arrays and std::array
Learn C++ arrays: declaring and initializing fixed-size arrays, indexing from 0, looping over arrays, out-of-bounds bugs, std::array with size() and at(), passing arrays to functions, and when to use std::vector instead.
On this page
An array stores a fixed number of values of the same type, one after another in memory. Each value is an element, and you reach it by its index, its position counting from 0.
C++ has two kinds of fixed-size array: the built-in C-style array, inherited from C, and std::array from the standard library. This lesson covers both. For collections that grow and shrink, you will use Vectors.
C-style arrays#
#include <iostream>
int main() {
int scores[5] = {72, 88, 95, 64, 81};
std::cout << "First: " << scores[0] << '\n';
std::cout << "Third: " << scores[2] << '\n';
scores[3] = 70; // change an element
std::cout << "Fourth: " << scores[3] << '\n';
}First: 72
Third: 95
Fourth: 70- The size (
5) is part of the declaration and cannot change. - Indexes run from
0tosize - 1, soscores[4]is the last element. - Elements you do not list are set to zero:
int counts[10] = {};gives ten zeros.
You can let the compiler count the elements: int primes[] = {2, 3, 5, 7}; creates an array of 4.
Looping over an array#
#include <iostream>
int main() {
double temps[] = {31.5, 29.0, 33.5, 30.0};
double sum = 0;
for (double t : temps) {
sum += t;
}
std::cout << "Average: " << sum / std::size(temps) << '\n';
for (std::size_t i = 0; i < std::size(temps); ++i) {
std::cout << "Day " << i + 1 << ": " << temps[i] << '\n';
}
}Average: 31
Day 1: 31.5
Day 2: 29
Day 3: 33.5
Day 4: 30std::size(array) (C++17) gives the number of elements. Older code uses sizeof(temps) / sizeof(temps[0]).
Out of bounds: no safety net#
C++ does not check indexes on C-style arrays. Reading or writing scores[5] in a 5-element array is undefined behaviour: it touches whatever memory comes next. The program might print garbage, silently corrupt another variable, or crash. These bugs are hard to find, so always keep loop conditions as i < size, never i <= size.
std::array: a safer fixed-size array#
std::array<Type, Size> (from <array>) is a thin wrapper around a C-style array with no extra cost, but it knows its own size, can be copied and compared, and offers a bounds-checked at():
#include <array>
#include <iostream>
#include <stdexcept>
int main() {
std::array<int, 4> marks = {56, 91, 78, 34};
std::cout << "Size: " << marks.size() << '\n';
std::cout << "Front: " << marks.front() << ", back: " << marks.back() << '\n';
try {
std::cout << marks.at(10) << '\n';
} catch (const std::out_of_range&) {
std::cout << "Index 10 is out of range\n";
}
}Size: 4
Front: 56, back: 34
Index 10 is out of rangemarks[10] would still be undefined behaviour; marks.at(10) throws an exception you can catch. In new code, prefer std::array over C-style arrays.
Copying and comparing#
C-style arrays cannot be assigned or compared with == (comparing them compares addresses, not contents). std::array works like a normal value:
#include <array>
#include <iostream>
int main() {
std::array<int, 3> a = {1, 2, 3};
std::array<int, 3> b = a; // copies every element
b[0] = 100;
std::cout << a[0] << ' ' << b[0] << '\n';
std::cout << std::boolalpha << (a == b) << '\n';
}1 100
falsePassing arrays to functions#
A C-style array passed to a function decays into a pointer to its first element, and the size is lost. You must pass the size separately. With std::array, the size is part of the type:
#include <array>
#include <iostream>
int sum_c(const int* data, std::size_t n) {
int total = 0;
for (std::size_t i = 0; i < n; ++i) total += data[i];
return total;
}
int sum_std(const std::array<int, 4>& data) {
int total = 0;
for (int x : data) total += x;
return total;
}
int main() {
int c_style[] = {1, 2, 3, 4};
std::array<int, 4> modern = {1, 2, 3, 4};
std::cout << sum_c(c_style, std::size(c_style)) << ' ' << sum_std(modern) << '\n';
}10 10A function that should accept arrays of any size is best written for std::vector, or for a std::span (C++20), which views any contiguous sequence.
Finding the largest element#
#include <array>
#include <iostream>
int main() {
std::array<int, 6> sales = {340, 120, 560, 410, 90, 560};
std::size_t best = 0;
for (std::size_t i = 1; i < sales.size(); ++i) {
if (sales[i] > sales[best]) {
best = i;
}
}
std::cout << "Best day: " << best + 1 << " with " << sales[best] << '\n';
}Best day: 3 with 560Using > (not >=) keeps the first best day when there is a tie.
Arrays or vectors?#
Use std::array when the number of elements is fixed and known (days of the week, RGB values). Use std::vector for everything else, which is most of the time.
Common mistakes#
Practice#
Practice exercise
Given std::array<int, 7> steps = {4200, 8100, 6700, 10200, 3900, 12000, 7600}; (steps walked each day of a week), print the total, the average (as a decimal) and how many days reached at least 8000 steps.
Show solution
#include <array>
#include <iostream>
int main() {
std::array<int, 7> steps = {4200, 8100, 6700, 10200, 3900, 12000, 7600};
int total = 0;
int goal_days = 0;
for (int s : steps) {
total += s;
if (s >= 8000) ++goal_days;
}
std::cout << "Total: " << total << '\n';
std::cout << "Average: " << static_cast<double>(total) / steps.size() << '\n';
std::cout << "Goal reached on " << goal_days << " days\n";
}Total: 52700
Average: 7528.57
Goal reached on 3 daysPractice exercise
Reverse a std::array<int, 6> a = {1, 2, 3, 4, 5, 6}; in place (without a second array) using a loop that swaps elements from both ends, then print it.
Show solution
#include <array>
#include <iostream>
#include <utility>
int main() {
std::array<int, 6> a = {1, 2, 3, 4, 5, 6};
for (std::size_t left = 0, right = a.size() - 1; left < right; ++left, --right) {
std::swap(a[left], a[right]);
}
for (int x : a) std::cout << x << ' ';
std::cout << '\n';
}6 5 4 3 2 1std::reverse(a.begin(), a.end()) from <algorithm> does the same in one call.
Key takeaway#
Finished this lesson?