Jak przekonwertować wektor na tablicę


352

Jak przekonwertować std::vector<double>na a double array[]?


9
Trochę nasuwa się pytanie, dlaczego? Możesz uzyskać dostęp do wektora jako tablicy. Co robi tablica, której nie robi wektor?
Michael Dorgan

96
@Michael Typowy przypadek użycia, który mam, to użycie wektora we własnym kodzie i konieczność wywołania funkcji innej firmy, która pobiera tablicę
Michał Mrożek

7
Rzucana terminologia jest myląca. Wskaźnik nie jest tablicą. Czy chcemy wskaźnik do pierwszego elementu tablicy, czy tablicy?
GManNickG

7
absolutnie prawdziwe pytanie - również dość proste, łatwe do interpretacji. proszę ponownie otworzyć.
dbliss,

10
„Trochę nasuwa pytanie, dlaczego?” - Po pierwsze, niewłaściwe użycie tego zwrotu. Po drugie, krwawi oczywiste dlaczego.
Jim Balter

Odpowiedzi:


533

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];

29
@ganuke Nie kopiujesz, tworzysz wskaźnik wskazujący na rzeczywistą tablicę, której wektor używa wewnętrznie. Jeśli chcesz skopiować odpowiedź GMana, wyjaśnij, jak
Michał Mrożek

4
@ganuke: Co to jest „tablica”? Musisz podać więcej informacji. Jaki jest wielki obraz?
GManNickG

6
@ganuke Nie, potrzebujesz tylko double*tego, który wskazuje na te same dane. Ta odpowiedź działa dokładnie w tej sprawie
Michael Mrozek

6
@guneykayim Wektor posiada tę pamięć, nie powinieneś jej zwalniać
Michael Mrozek

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

148

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 vjest wektor doubles. 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 arrjest wystarczająco duży, ale że arrsię zapełni lub masz niezainicjowane wartości.


15
Uwaga: użyj v.size (), aby uzyskać liczbę elementów dla nowej tablicy: double arr [v.size ()];
rbaleksandar,

7
@rbaleksandar: Tablice nie mogą mieć nie stałej wielkości wyrażenia.
GManNickG,

@GManNickG: Działa, ale myślę, że jest tu trochę nieporozumień. Wyobraź sobie, że: masz klasę z szeregiem wskaźników różnych typów, które muszą wskazywać na tablice, które nie są znane w momencie definiowania twojej klasy i które są później tworzone przez opróżnianie różnych wektorów i użycie ich parametru size aby określić, ile miejsca ma zostać wykorzystane. Kolejny przykład: prosta funkcja void arrayTest (unsigned int arrSize), która tworzy w niej tablicę (short arr [arrSize];) za pomocą parametru funkcji dla wielkości.
rbaleksandar

1
@rbaleksandar Bez nieporozumień; w C ++ 11 i wcześniejszych rozmiarach tablic muszą być integralnymi stałymi wyrażeniami. Twój przykład funkcji jest powszechnym zastosowaniem dla VLA w C, ale obsługiwany tylko przez (niestandardowe) rozszerzenie w C ++. Może jednak pochodzić z C ++ 14: stackoverflow.com/a/17318040/87234 . Ale na razie nie jest to po prostu standardowa opcja.
GManNickG,

1
@GManNickG Myślę, że @Jet mówi, że jeśli chcesz przekonwertować wektor na tablicę i zamierzasz zmienić tablicę za pomocą size()funkcji std:vector, musisz użyć newlub malloczrobić 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ę.
RyanP,


17
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, thearraygdy thevectorjest objęty zakresem.


4
... i upewnij się, że wektor nie jest empty(), w przeciwnym razie wywołałoby to przerażającego UB.
sbi

13

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.


1
Myślę, że miałeś na myśli f( &v[0] );ostatnią linię
Michael Mrozek

10

Co do std::vector<int> vecvec, aby uzyskać int*, możesz użyć dwóch metod:

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

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

Jeśli chcesz przekonwertować dowolny Twektor typu T* array, po prostu zamień powyższy intna 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.

wprowadź opis zdjęcia tutaj

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)
}

2

Możemy to zrobić za pomocą metody data (). C ++ 11 zapewnia tę metodę.

Fragment kodu

#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;
}


1

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ć.


-1

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;
        }
    }
}

v [i] [j]; dla tablicy 2d
Sakthi Vignesh
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.