ITA - Appunti Cpp 004 - Vettori
November 2023 (1124 Words, 7 Minutes)
Definizione di un array c-style
Un array è una sequenza di elementi dello stesso tipo, conservata in porzioni di memoria contigue. Ad un array è associato un identificativo che può essere indicizzato numericamente per accedere ai singoli elementi. La prima locazione dell’array è associata all’indice 0, e coincide con l’indirizzo dell’indentificativo stesso.
Un array ha una dimensione costante che deve essere specificato nella sua dichiarazione o desumibile della sua definizione.
#include <iostream>
#include <iterator>
#include <numeric>
int main{
// dichiarazione senza inizializzazione, con dimensione pari a 5
int myArray[5];
// dichiarazione e definizione, la dimensione è desunta dal compilatore
int myArray[] {2, 4, 6, 8, 10};
}
Trasformazione da array a puntatore
Esiste una conversione implicita da lvalue a rvalue di tipo array a rvalue di tipo puntatore: costruisce un puntatore al primo elemento di un array. Questa conversione viene utilizzata ogni volta che gli array appaiono in un contesto in cui non sono previsti array.
#include <iostream>
#include <iterator>
#include <numeric>
void g(int (&a)[3])
{
std::cout << a[0] << '\n';
}
void f(int* p)
{
std::cout << *p << '\n';
}
int main()
{
int a[3] = {1, 2, 3};
int* p = a;
std::cout << sizeof a << '\n' // stampa la dimensione dell'array
<< sizeof p << '\n'; // stampa la dimensione del puntatore
// nei contensti in cui sono consentiti solo gli array, l'uso di un puntatore
// deve essere evitato
g(a); // ok: la funzione accetta il riferimento a un array
// g(p); // errore
for (int n : a) // ok: gli array possono essere usati nei ranged-for loops
std::cout << n << ' '; // stampa gli elementi dell'array
// for (int n : p) // errore
// std::cout << n << ' ';
std::iota(std::begin(a), std::end(a), 7); // ok
// std::iota(std::begin(p), std::end(p), 7); // errore
// dove i puntatori sono accettati, entrambi possono essere usati:
f(a); // ok
f(p); // ok
std::cout << *a << '\n' // stampa il primo elemento
<< *p << '\n' // lo stesso
<< *(a + 1) << ' ' << a[1] << '\n' // stampa il secondo elemento
<< *(p + 1) << ' ' << p[1] << '\n'; // lo stesso
}
Matrici
Le matrici sono array di array…
// array di 2 arrays composti da 3 int l'uno
int a[2][3] = { {1, 2, 3}, // può essere vista come una matrice 2 × 3
{4, 5, 6} }; // con una disposione in fila
int a[2]; // array di 2 int
int* p1 = a; // trasformazione a puntatore del primo elemento
int b[2][3]; // matrice di 2 x 3 int
// int** p2 = b; // errore: b non è trasformabile in int**
int (*p2)[3] = b; // b decade al puntatore all'array dei primi 3 lementi di b
int c[2][3][4]; // array di 2 arrays di 3 arrays di 4 int
// int*** p3 = c; // errore: c non è trasformabile in int***
int (*p3)[3][4] = c; // c decade a un puntatore de primo piano 3 × 4-elementi di c
NB: quando una trasformazione array-to-pointer è applicata a una matrice, viene fatto solo una volta
Uso di un std::array
std::array
è un container che incapsula gli arrays, la semantica è uguale a quella degli array, ad eccezione che non decadono a T*
automaticamente.
Questa struttura combina le prestazioni e l’accessibilità di un array c-style con i benefici di un container standard, come la dimensione nota, supporto all’allassegnazione, iteratori ecc…
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
int main()
{
// La definizione con dati aggregati
std::array<int, 3> a1{ {1, 2, 3} }; // Prima del C++11 erano necessarie le doppie parentesi
// dopo la revisione CWG 1270, dal C++14 in avanti non sono
// più necessarie
// operazioni relative ai container
std::sort(a1.begin(), a1.end());
std::ranges::reverse_copy(a2, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
// supporto a cicli
std::array<std::string, 2> a3{"E", "\u018E"};
for (const auto& s : a3)
std::cout << s << ' ';
std::cout << '\n';
}
Definizione di una vettore
I vettori sono implementati in modi diversi:
- std::vector è un contenitore che incapsula array a dimensione dinamica.
- std::pmr::vector è un template alias che usa gli allocatori polimorfi.
#include <iostream>
#include <vector>
int main()
{
// Creare un vettore che contiene interi
std::vector<int> v = {8, 4, 5, 9};
// aggiungi due elementi
v.push_back(6);
v.push_back(9);
// sovrascrivi l'elemento al secondo posto
v[2] = -1;
// Stampa il vettore
for (int n : v)
std::cout << n << ' ';
std::cout << '\n';
}
Riferimenti
- cppreference.com - vector
- https://en.cppreference.com/w/cpp/container/array
- stackoverflow.com - stdvector versus stdarray in c
- stackoverflow.com - arrays vs vectors introductory similarities and differences
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale Theme Moonwalk