Come convertire vettore in array


352

Come faccio a convertire a std::vector<double>in a double array[]?


9
Kinda pone la domanda sul perché? È possibile accedere a un vettore come un array. Cosa fa una matrice che un vettore non fa?
Michael Dorgan,

96
@Michael Il tipico caso d'uso che ho è l'uso di un vettore nel mio codice e la necessità di chiamare una funzione di terze parti che accetta un array
Michael Mrozek,

7
La terminologia che viene lanciata è confusa. Un puntatore non è un array. Vogliamo un puntatore al primo elemento di un array o un array?
GManNickG

7
assolutamente una vera domanda - anche abbastanza semplice, facilmente interpretabile. per favore riaprire.
Dbliss,

10
"Kinda pone la domanda sul perché?" - Primo, uso improprio di quella frase. In secondo luogo, sanguina evidente perché.
Jim Balter,

Risposte:


533

C'è un trucco abbastanza semplice per farlo, poiché le specifiche ora garantiscono che i vettori memorizzino i loro elementi in modo contiguo:

std::vector<double> v;
double* a = &v[0];

29
@ganuke Non stai copiando, stai facendo un puntatore che punta alla matrice effettiva che il vettore sta usando internamente. Se vuoi copiare la risposta di GMan spiega come
Michael Mrozek,

4
@ganuke: che cos'è "l'array"? Devi fornire maggiori informazioni. Qual è il quadro generale?
GManNickG,

6
@ganuke In caso contrario, hai solo bisogno double*che punti agli stessi dati. Questa risposta funziona esattamente per quel caso
Michael Mrozek,

6
@guneykayim Il vettore possiede quel ricordo, non dovresti liberarlo
Michael Mrozek,

23
std::vector<double> v; double* a = v.data();
sinoTrinity,

148

Per che cosa? È necessario chiarire: è necessario un puntatore al primo elemento di un array o un array?

Se stai chiamando una funzione API che prevede la prima, puoi fare do_something(&v[0], v.size()), dove vè un vettore di doubles. Gli elementi di un vettore sono contigui.

Altrimenti, devi solo copiare ogni elemento:

double arr[100];
std::copy(v.begin(), v.end(), arr);

Assicurati che non solo thar arrsia abbastanza grande, ma che arrsi riempia o che tu abbia valori non inizializzati.


15
Nota: utilizzare v.size () per ottenere il numero di elementi per il nuovo array: double arr [v.size ()];
rbaleksandar,

7
@rbaleksandar: le matrici non possono avere una dimensione di espressione non costante.
GManNickG,

@GManNickG: Funziona ma penso che ci siano dei malintesi qui. Immagina quanto segue: hai una classe con un sacco di puntatori di vari tipi che devono puntare ad array, che non sono noti al momento in cui definisci la tua classe e che sono successivamente creati scaricando vari vettori e usando il loro parametro size per determinare quanto spazio deve essere utilizzato. Un altro esempio: una semplice funzione void arrayTest (unsigned int arrSize), che crea un array (short arr [arrSize];) usando il suo parametro-funzione per la dimensione.
rbaleksandar, il

1
@rbaleksandar Nessun equivoco; in C ++ 11 e precedenti, le dimensioni degli array devono essere espressioni costanti integrali. Il tuo esempio di funzione è un uso comune per VLA in C, ma è supportato solo dall'estensione (non standard) in C ++. È possibile che arrivi a C ++ 14: stackoverflow.com/a/17318040/87234 . Ma per ora, semplicemente non è un'opzione standard.
GManNickG,

1
@GManNickG Penso che @Jet stia dicendo che se si desidera convertire un vettore in un array, e si intende dimensionare l'array utilizzando la size()funzione del, std:vectorè necessario utilizzare newo mallocper farlo. Come è stato già sottolineato (da te) ciò double arr[v.size()]non è valido. L'uso del vettore al posto del nuovo è una buona idea, ma l'intero punto della domanda è come è possibile convertire un vettore in un array.
RyanP,


17
vector<double> thevector;
//...
double *thearray = &thevector[0];

Questo è garantito per funzionare dallo standard, tuttavia ci sono alcuni avvertimenti: in particolare, fare attenzione a usare solo thearraymentre thevectorè nell'ambito.


4
... e assicurati che il vettore non lo sia empty(), altrimenti ciò invocherebbe il temuto UB.
sbi,

13

I vettori sono in effetti matrici sotto la pelle. Se hai una funzione:

void f( double a[]);

puoi chiamarlo così:

vector <double> v;
v.push_back( 1.23 )
f( &v[0] );

Non dovresti mai aver bisogno di convertire un vettore in un'istanza di array reale.


1
Credo che si intende f( &v[0] );per la vostra ultima linea
Michael Mrozek

10

Per quanto riguarda std::vector<int> vec, vec per ottenere int*, è possibile utilizzare due metodi:

  1. int * arr = & vec [0];

  2. int * arr = vec.data ();

Se si desidera convertire qualsiasi tipo Tdi vettore a T* array, basta sostituire il sopra inta T.

Ti mostrerò perché le due precedenti funzionano, per una buona comprensione?

std::vector è essenzialmente un array dinamico.

Membro dei dati principali come di seguito:

template <class T, class Alloc = allocator<T>>
class vector{
    public:
        typedef T          value_type;
        typedef T*         iterator;
        typedef T*         pointer;
        //.......
    private:
        pointer start_;
        pointer finish_;
        pointer end_of_storage_;

    public:
        vector():start_(0), finish_(0), end_of_storage_(0){}
    //......
}

L' range (start_, end_of_storage_)vale a memoria di matrice vettore allocare;

L' range(start_, finish_)vale a memoria di matrice vettore utilizzato;

La range(finish_, end_of_storage_)è la memoria di matrice di backup.

Ad esempio, per quanto riguarda un vettore vec. che ha {9, 9, 1, 2, 3, 4} è che il puntatore potrebbe gradire quanto segue.

inserisci qui la descrizione dell'immagine

Quindi &vec[0]= start_ (indirizzo.) (Start_ è equivalente a int * array head)

c++11 Nella data()funzione membro solo ritorno start_

pointer data()
{ 
     return start_; //(equivalent to `value_type*`, array head)
}

2

Possiamo farlo usando il metodo data (). C ++ 11 fornisce questo metodo.

Snippet di codice

#include<bits/stdc++.h>
using namespace std;


int main()
{
  ios::sync_with_stdio(false);

  vector<int>v = {7, 8, 9, 10, 11};
  int *arr = v.data();

  for(int i=0; i<v.size(); i++)
  {
    cout<<arr[i]<<" ";
  }

  return 0;
}

2
std::vector<double> vec;
double* arr = vec.data();

1

Se si dispone di una funzione, allora probabilmente bisogno di questo: foo(&array[0], array.size());. Se sei riuscito a entrare in una situazione in cui hai bisogno di un array, allora devi refactoring, i vettori sono sostanzialmente array estesi, dovresti sempre usarli.


-1

Puoi fare qualcosa del genere

vector <int> id;
vector <double> v;

if(id.size() > 0)
{
    for(int i = 0; i < id.size(); i++)
    {
        for(int j = 0; j < id.size(); j++)
        {
            double x = v[i][j];
            cout << x << endl;
        }
    }
}

v [i] [j]; per 2d array
Sakthi Vignesh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.