HOWTO · C++
Converti vettore in array in C++
Questo articolo introduce come convertire un vettore in un array in C++
In questa pagina
Un std::vector memorizza i propri elementi in posizioni contigue, quindi le API che accettano un puntatore e il numero di elementi possono usare direttamente la sua memoria. Questo consente un accesso simile a quello di un array, ma non crea un array separato: il puntatore fa riferimento a elementi posseduti dal vettore. Se il codice chiamante ha bisogno di una memoria indipendente, copia gli elementi in una destinazione di dimensioni adeguate.
Usa data() per ottenere temporaneamente una vista tramite puntatore, std::copy per creare una copia indipendente e std::transform quando vuoi modificare i valori durante la copia. Mantieni in vita il vettore finché usi un puntatore ai suoi elementi. Le operazioni che riallocano il vettore rendono inutilizzabili i puntatori alla sua memoria.
Usa data() per accedere agli elementi di un vettore come a un array
Il membro data() restituisce un puntatore alla memoria contigua degli elementi del vettore. Abbinalo a size() quando passi i dati a un’API che accetta un puntatore e un conteggio. Il puntatore fa riferimento agli stessi elementi del vettore: scriverci tramite modifica l’elemento corrispondente. Non deve restare valido oltre la durata del vettore né oltre un’operazione che ne rialloca la memoria.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{1, 2, 3};
int* elements = values.data();
elements[1] = 20;
for (std::size_t i = 0; i < values.size(); ++i) {
if (i != 0) std::cout << ' ';
std::cout << elements[i];
}
std::cout << '\n';
}
1 20 3
Per un vettore che può essere vuoto, è possibile ottenere data(), ma non dereferenziare il puntatore restituito se non esiste alcun elemento. Quando accedi agli elementi tramite il puntatore, usa sempre la dimensione del vettore come limite.
Usa l’operatore indirizzo con un vettore non vuoto
Se sai che il vettore contiene almeno un elemento, &values[0] punta al primo elemento e consente di accedere tramite indice agli elementi del vettore. Il puntatore ha la stessa proprietà e durata di quello ottenuto con data(). Questa precondizione è essenziale: accedere all’elemento zero quando il vettore è vuoto non è valido. Se il vettore potrebbe essere vuoto, preferisci data(); verifica comunque la dimensione prima di dereferenziare il puntatore o passarlo a codice che richiede almeno un elemento.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{4, 5, 6};
int* elements = &values[0];
for (std::size_t i = 0; i < values.size(); ++i) {
if (i != 0) std::cout << ' ';
std::cout << elements[i];
}
std::cout << '\n';
}
4 5 6
Copia gli elementi del vettore in un array con std::copy()
std::copy scrive ogni elemento sorgente in un intervallo di destinazione già creato; non alloca tale intervallo. Se il numero di elementi è noto in fase di compilazione, std::array fornisce un vero oggetto array di dimensione fissa. La sua dimensione e il tipo degli elementi devono essere sufficienti per contenere la sorgente. Se il numero è noto solo durante l’esecuzione, usa una memoria dinamica adeguata, ad esempio un std::vector di destinazione oppure un array dinamico di cui gestisci la proprietà, se l’API chiamante ne richiede espressamente uno.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
#include <algorithm>
#include <array>
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{7, 8, 9};
std::array<int, 3> result{};
std::copy(values.begin(), values.end(), result.begin());
for (std::size_t i = 0; i < result.size(); ++i) {
if (i != 0) std::cout << ' ';
std::cout << result[i];
}
std::cout << '\n';
}
7 8 9
La destinazione è indipendente dalla sorgente, quindi modificare result non modifica values. Prima di chiamare std::copy, assicurati che la destinazione possa contenere tutti gli elementi sorgente: l’algoritmo non ne controlla la capacità. Un array incorporato di lunghezza variabile non fa parte dello standard C++, perché il suo limite deve essere una costante nota in fase di compilazione.
Trasforma gli elementi del vettore durante la copia con std::transform()
Usa std::transform quando vuoi calcolare nuovi valori durante la copia. Come per std::copy, l’intervallo di destinazione deve poter contenere un risultato per ogni elemento in ingresso. Questo esempio raddoppia ogni intero e lo memorizza in uno std::array indipendente.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
#include <algorithm>
#include <array>
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{2, 3, 4};
std::array<int, 3> doubled{};
std::transform(values.begin(), values.end(), doubled.begin(),
[](int value) { return value * 2; });
for (std::size_t i = 0; i < doubled.size(); ++i) {
if (i != 0) std::cout << ' ';
std::cout << doubled[i];
}
std::cout << '\n';
}
4 6 8
Per una copia senza modifiche, std::copy esprime l’intento in modo più diretto. Scegli un tipo di destinazione che possa contenere i risultati trasformati e dimensionala per l’intero intervallo di ingresso.
Copia gli elementi del vettore con un ciclo for
Un ciclo offre un controllo esplicito su ogni assegnazione. Vale lo stesso requisito relativo alla dimensione della destinazione: ogni indice valido per la sorgente deve essere valido anche per la destinazione. Se la destinazione ha una dimensione fissa nota in fase di compilazione, verifica che la sua estensione corrisponda a quella del vettore prima di copiare; per un ingresso di dimensione nota solo durante l’esecuzione, usa una destinazione dinamica di dimensioni adeguate.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
#include <array>
#include <cstddef>
#include <iostream>
#include <vector>
int main() {
std::vector<int> values{10, 11, 12};
std::array<int, 3> result{};
for (std::size_t i = 0; i < values.size(); ++i) {
result[i] = values[i];
}
for (std::size_t i = 0; i < result.size(); ++i) {
if (i != 0) std::cout << ' ';
std::cout << result[i];
}
std::cout << '\n';
}
10 11 12
Scegli data() quando un’API richiede una vista temporanea sugli elementi posseduti dal vettore e mantieni il vettore valido e invariato per tutta la durata dell’uso. Usa std::copy quando serve una memoria separata, std::transform quando vuoi modificare i valori durante la copia e un ciclo quando è utile controllare ogni elemento. Uno std::array di dimensione fissa è adatto quando il numero di elementi è noto in fase di compilazione; altrimenti, se l’API lo consente, usa una destinazione ridimensionabile durante l’esecuzione.