Fixed-sized arrays in C++ can be implemented using std::array
and C-style arrays. This chapter covers both implementations and their usage.
std::array
std::array
is a container that encapsulates fixed-size arrays. It provides better type safety and features compared to C-style arrays.
#include <array> // for std::array
std::array<int, 5> a; // Members default initialized (int elements are left uninitialized)
std::array<int, 5> b{}; // Members value initialized (int elements are zero initialized) (preferred)
// Length must be constexpr, enum, or macro
constexpr std::array a1 { 9, 7, 5, 3, 1 }; // The type is deduced to std::array<int, 5>
constexpr auto myArray2 { std::to_array<int>({ 9, 7, 5, 3, 1 }) }; // Specify type only, deduce size
arr.size();
std::size(arr);
std::ssize(arr); // C++20
std::cout << std::get<3>(arr); // print the value of element with index 3
// std::cout << std::get<9>(arr); // invalid index (compile error)
std::array
to Functionsvoid passByRef(const std::array<int, 5>& arr);
template <typename T, std::size_t N>
void passByRef(const std::array<T, N>& arr);
template <std::size_t N>
void passByRef(const std::array<int, N>& arr); // We've defined the element type as int
struct House
{
int number{};
int stories{};
int roomsPerStory{};
};
std::array<House, 1> houses{};
houses[0] = { 13, 1, 7 };
constexpr std::array houses { House{ 13, 1, 7 } }; // CTAD
constexpr std::array<House, 3> houses { // initializer for houses
{ // extra set of braces to initialize the C-style array member with implementation-defined name
{ 13, 4, 30 }, // initializer for array element 0
}
};
constexpr std::array<House, 3> houses
{
._Elems{
{ 13, 1, 7 }
}
};
std::reference_wrapper
#include <functional> // for std::reference_wrapper
int x { 5 };
int y { 6 };
int z { 7 };
std::array<std::reference_wrapper<int>, 3> arr { x, y, z };
arr[1].get() = 5; // modify the object in array element 1
auto ref { std::ref(x) }; // C++11, deduces to std::reference_wrapper<int>
auto cref { std::cref(x) }; // C++11, deduces to std::reference_wrapper<const int>
C-style arrays are the traditional array type in C++, but they have several limitations compared to std::array
.
int testScore[30] {};
int prime[5] { 2, 3, 5, 7, 11 };
int prime[] = { 2, 3, 5, 7, 11 }; // no length in []
sizeof(prime); // prints 20 (assuming 4 byte ints)
std::size(prime); // C++17, returns unsigned integral value 5
std::ssize(prime); // C++20, returns signed integral value 5
sizeof(array) / sizeof(array[0]);
template <typename T, std::size_t N>
constexpr std::size_t length(const T(&)[N]) noexcept
{ return N; }
void printElementZero(const int arr[]) // treated the same as const int*
{
std::cout << arr[0];
}
int x {};
const int* ptr{ &x }; // assume 4 byte ints
ptr; // 00AFFD80
(ptr + 1); // 00AFFD84
(ptr - 1); // 00AFFD76
ptr = &arr[3];
*(ptr+1), ptr[1]; // arr[4]
C-style strings are arrays of characters ending with a null terminator (\0
).
const char str2[]{ "123" }; // const char[4], +1 for null terminator
const char name[] { "Alex" }; // const C-style string initialized with C-style string literal
const char* const color{ "Orange" }; // const pointer to C-style string literal
char rolls[255] {}; // declare array large enough to hold 254 characters + null terminator
std::cin.getline(rolls, std::size(rolls));
strlen()
-- returns the length of a C-style string.strcpy()
, strncpy()
, strcpy_s()
-- overwrites one C-style string with another.strcat()
, strncat()
-- Appends one C-style string to the end of another.strcmp()
, strncmp()
-- Compares two C-style strings (returns 0
if equal).int a[3][5]{}; // a[row][col], C++ uses row-major order
int a[][][]{}; // there can be more dimensions
int array[3][5] // can omit (only) the leftmost length specification
{
{ 1, 2, 3, 4, 5 }, // row 0
{ 6, 7, 8, 9, 10 }, // row 1
{ 11, 12, 13, 14, 15 } // row 2
};
std::array
Multi-Dimensional Arraysstd::array<std::array<int, 4>, 3> arr {{ // note double braces
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }}};
// std::array<std::array<int, col>, row> is backwards
using Array2dint34 = std::array<std::array<int, 4>, 3>;
// An alias template for a two-dimensional std::array
template <typename T, std::size_t Row, std::size_t Col>
using Array2d = std::array<std::array<T, Col>, Row>;
arr[0].size(), arr[0][0].size();
Fixed-sized arrays in C++ can be implemented using std::array
and C-style arrays. std::array
provides better type safety and features, while C-style arrays offer more flexibility at the cost of safety and ease of use. Understanding both types and their usage is crucial for writing efficient and maintainable C++ code.