Array
Containerul array din modulul cu același nume <array> reprezintă un analog al unui tablou (array). De asemenea, are o dimensiune fixă.
Definire și inițializare
Pentru a crea un obiect array, în paranteze unghiulare după denumirea tipului trebuie să specificăm tipul și dimensiunea:
#include <array>
int main()
{
std::array<int, 5> numbers; // conține 5 numere de tip int
}
În acest caz este definit un obiect array format din 5 numere de tip int. Implicit, toate elementele containerului au valori nedefinite.
Pentru a inițializa containerul cu anumite valori, se poate folosi un inițializator – se transmit valorile între acolade:
std::array<int, 5> numbers {}; // conține 5 zerouri
În acest caz, inițializatorul gol va inițializa toate elementele containerului numbers cu zero. De asemenea, se pot specifica direct anumite valori:
std::array<int, 5> numbers {2, 3, 4, 5, 6};
Dimensiunea fixă impune o restricție la inițializare: numărul valorilor transmise containerului nu trebuie să depășească dimensiunea acestuia. Se pot transmite mai puține valori – acestea vor fi alocate primelor elemente, iar restul vor fi inițializate cu valoarea implicită (de exemplu, 0 pentru tipurile întregi):
std::array<int, 5> numbers {2, 3, 4}; // {2, 3, 4, 0, 0}
Totuși, dacă se transmit mai multe valori decât dimensiunea containerului, va apărea o eroare.
Este de menționat că, începând cu standardul C++17, la inițializare se poate omite specificarea tipului și a numărului de elemente – compilatorul le va deduce automat pe baza listei de inițializare:
std::array numbers {2, 3, 4, 5, 6};
Totuși, în acest caz lista dintre acolade trebuie să conțină cel puțin o valoare.
Accesul la elemente
Pentru a accesa elementele unui array, se poate folosi aceeași sintaxă ca la tablouri – se folosește indicele între paranteze drepte:
#include <array>
#include <iostream>
int main()
{
std::array<int, 5> numbers {2, 3, 4, 5, 6};
// obținem valoarea unui element
int n = numbers[2];
std::cout << "n = " << n << std::endl; // n = 4
// modificăm valoarea elementului
numbers[2] = 12;
std::cout << "numbers[2] = " << numbers[2] << std::endl; // numbers[2] = 12
}
Parcurgerea containerului
Containerul array poate fi parcurs cu cicluri standard:
#include <iostream>
#include <array>
#include <string>
int main()
{
const unsigned n = 5;
std::array<std::string, n> people { "Tom", "Alice", "Kate", "Bob", "Sam" };
// acces prin indici
for(int i{}; i < n; i++)
{
std::cout << people[i] << std::endl;
}
std::cout << std::endl;
// parcurgere secvențială
for (auto person : people)
{
std::cout << person << std::endl;
}
}
Funcții de bază ale array
Într-un container array nu se pot adăuga sau elimina elemente. Funcțiile de bază care pot fi utilizate:
- size(): returnează dimensiunea containerului
- at(index): returnează elementul de la indexul index
- front(): returnează primul element
- back(): returnează ultimul element
- fill(n): atribuie fiecărui element valoarea n
Exemplu de utilizare:
#include <iostream>
#include <array>
#include <string>
int main()
{
std::array<std::string, 3> people { "Tom", "Bob", "Sam" };
std::string second = people.at(1); // Bob
std::string first = people.front(); // Tom
std::string last = people.back(); // Sam
std::cout << second << std::endl; // Bob
std::cout << first << std::endl; // Tom
std::cout << last << std::endl; // Sam
// atribuim "Undefined" tuturor elementelor
people.fill("Undefined"); // people = { "Undefined", "Undefined", "Undefined" }
// verificăm
for (int i{}; i< people.size(); i++)
{
std::cout << people[i] << std::endl;
}
}
Deși obiectele array seamănă cu tablourile obișnuite, tipul array este mai flexibil. De exemplu, nu putem atribui direct valorile unui tablou altui tablou. În schimb, unui obiect array îi putem atribui valorile altui obiect array:
std::array<int, 5> numbers1 { 1, 2, 3, 4, 5 };
std::array<int, 5> numbers2 = numbers1; // este permis
int nums1[] = { 1,2,3,4,5 };
//int nums2[] = nums1; // nu este permis
Putem compara, de asemenea, două containere array:
std::array<int, 5> numbers1 { 1, 2, 3, 4, 5 };
std::array<int, 5> numbers2 { 1, 2, 3, 4, 5 };
std::cout << std::boolalpha << (numbers1 == numbers2) << std::endl; // true
std::cout << std::boolalpha << (numbers1 != numbers2) << std::endl; // false
std::cout << std::boolalpha << (numbers1 > numbers2) << std::endl; // false
std::cout << std::boolalpha << (numbers1 < numbers2) << std::endl; // false
Două containere sunt comparate element cu element. În exemplul de mai sus este clar că numbers1 și numbers2 sunt egale. În schimb, compararea tablourilor clasice este considerată învechită începând cu standardul C++20.