Jak przekonwertować std::vector<double>
na a double array[]
?
Jak przekonwertować std::vector<double>
na a double array[]
?
Odpowiedzi:
Jest to dość prosta sztuczka, ponieważ specyfikacja gwarantuje teraz, że wektory przechowują swoje elementy w sposób ciągły:
std::vector<double> v;
double* a = &v[0];
double*
tego, który wskazuje na te same dane. Ta odpowiedź działa dokładnie w tej sprawie
std::vector<double> v; double* a = v.data();
Po co? Musisz wyjaśnić: Czy potrzebujesz wskaźnika do pierwszego elementu tablicy, czy tablicy?
Jeśli wywołujesz funkcję API, która oczekuje pierwszej, możesz zrobić do_something(&v[0], v.size())
, gdzie v
jest wektor double
s. Elementy wektora są ciągłe.
W przeciwnym razie wystarczy skopiować każdy element:
double arr[100];
std::copy(v.begin(), v.end(), arr);
Upewnij się, że nie tylko thar arr
jest wystarczająco duży, ale że arr
się zapełni lub masz niezainicjowane wartości.
size()
funkcji std:vector
, musisz użyć new
lub malloc
zrobić to. Jak już zostało wskazane (przez ciebie), double arr[v.size()]
to nie jest poprawne. Używanie wektora zamiast nowego jest dobrym pomysłem, ale cała kwestia dotyczy tego, jak przekonwertować wektor na tablicę.
vector<double> thevector;
//...
double *thearray = &thevector[0];
Jest to gwarantowane, że działa zgodnie ze standardem, jednak istnieją pewne zastrzeżenia: w szczególności uważaj, aby używać tylko, thearray
gdy thevector
jest objęty zakresem.
empty()
, w przeciwnym razie wywołałoby to przerażającego UB.
Wektory skutecznie to tablice pod skórą. Jeśli masz funkcję:
void f( double a[]);
możesz to tak nazwać:
vector <double> v;
v.push_back( 1.23 )
f( &v[0] );
Nie trzeba nigdy przekształcać wektora w rzeczywistą instancję tablicy.
f( &v[0] );
ostatnią linię
Co do std::vector<int> vec
vec, aby uzyskać int*
, możesz użyć dwóch metod:
int * arr = & vec [0];
int * arr = vec.data ();
Jeśli chcesz przekonwertować dowolny T
wektor typu T* array
, po prostu zamień powyższy int
na T
.
Pokażę ci, dlaczego powyższe dwa działa, dla dobrego zrozumienia?
std::vector
jest zasadniczo tablicą dynamiczną.
Główny członek danych, jak poniżej:
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){}
//......
}
Jest range (start_, end_of_storage_)
to cała pamięć macierzy, którą przydziela wektor;
Jest range(start_, finish_)
to cała pamięć tablicowa, której użył wektor;
Jest range(finish_, end_of_storage_)
to pamięć macierzy kopii zapasowych.
Na przykład co do wektora vec. który ma {9, 9, 1, 2, 3, 4} to wskaźnik może polubić poniżej.
So &vec[0]
= start_ (adres.) (Start_ jest równoważne int * head tablicy)
W c++11
tej data()
funkcji użytkownik po prostu wrócić start_
pointer data()
{
return start_; //(equivalent to `value_type*`, array head)
}
Możemy to zrobić za pomocą metody data (). C ++ 11 zapewnia tę metodę.
#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;
}
Jeśli masz funkcję, to prawdopodobnie potrzebujesz to: foo(&array[0], array.size());
. Jeśli udało ci się dostać do sytuacji, w której potrzebujesz tablicy, musisz refaktoryzować, wektory są w zasadzie rozszerzonymi tablicami, zawsze powinieneś ich używać.
Możesz zrobić coś takiego
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;
}
}
}