Vektör diziye nasıl dönüştürülür


352

Nasıl dönüştürebilirim std::vector<double>a double array[]?


9
Neden böyle bir soru soruyor? Bir vektöre dizi olarak erişebilirsiniz. Bir dizi, bir vektörün yapmadığı ne yapar?
Michael Dorgan

96
@Michael Sahip olduğum tipik kullanım durumu, kendi kodumda bir vektör kullanmak ve bir dizi alan bir üçüncü taraf işlevini çağırmak gerekiyor
Michael Mrozek

7
Fırlatılan terminoloji kafa karıştırıcı. İşaretçi bir dizi değildir. Bir dizinin veya bir dizinin ilk öğesine bir işaretçi istiyor muyuz?
GManNickG

7
kesinlikle gerçek bir soru - oldukça basit, kolayca yorumlanabilen bir soru. lütfen tekrar açın.
dbliss

10
"Neden böyle bir soru soruyor?" - Öncelikle, bu ifadeyi kötüye kullan. İkincisi, neden kanıyor.
Jim Balter

Yanıtlar:


534

Spesifikasyon şimdi vektörlerin öğelerini bitişik olarak saklamasını garanti ettiğinden , bunu yapmak için oldukça basit bir hile var :

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

29
@ganuke Kopyalama yapmıyorsunuz, vektörün dahili olarak kullandığı gerçek diziye işaret eden bir işaretçi oluşturuyorsunuz. GMan'ın cevabını kopyalamak istiyorsanız nasıl olduğunu açıklar
Michael

4
@ganuke: "Dizi" nedir? Daha fazla bilgi vermeniz gerekiyor. Büyük resim nedir?
GManNickG

6
@ganuke Yapmazsın, sadece double*aynı verilere işaret eden bir şeye ihtiyacın var . Bu cevap tam da bu davada işe yarıyor
Michael Mrozek

6
@guneykayim Vektör bu hafızanın sahibi, onu boşaltmamalısın
Michael Mrozek

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

148

Ne için? Açıklığa kavuşturmanız gerekiyor: Bir dizinin ilk öğesinin veya dizinin bir işaretçisine mi ihtiyacınız var?

Birincisini bekleyen bir API işlevi çağırıyorsanız, bunu yapabilirsiniz do_something(&v[0], v.size()), nerede s vvektörü double. Bir vektörün elemanları bitişiktir.

Aksi takdirde, her bir öğeyi kopyalamanız yeterlidir:

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

Sadece thar'ın arryeterince büyük olmadığından emin olun , ancak arrdoldurulur veya başlatılmamış değerleriniz vardır.


15
Not: yeni dizi için öğe sayısını almak için v.size () kullanın: double arr [v.size ()];
rbaleksandar

7
@rbaleksandar: Dizilerin sabit olmayan bir ifade boyutu olamaz.
GManNickG

@GManNickG: Çalışıyor ama bence burada yanlış anlaşılma var. Aşağıdakileri hayal edin: sınıfınızı tanımladığınız anda bilinmeyen ve daha sonra çeşitli vektörleri yıkayarak ve boyut parametrelerini kullanarak oluşturulan dizilere işaret etmesi gereken çeşitli türlerde bir grup işaretçi içeren bir sınıfınız var. ne kadar alan kullanılacağını belirlemek için. Başka bir örnek: boyut için işlev parametresini kullanarak içinde bir dizi (kısa arr [arrSize];) oluşturan basit bir işlev void arrayTest (unsigned int arrSize).
rbaleksandar

1
@rbaleksandar Yanlış anlama yok; C ++ 11 ve öncesinde, dizi boyutları tümleşik sabit ifadeler olmalıdır. İşlev örneğiniz, C'deki VLA'lar için yaygın bir kullanımdır, ancak yalnızca C ++ 'da (standart olmayan) uzantı tarafından desteklenir. Yine de C ++ 14'e gelebilir: stackoverflow.com/a/17318040/87234 . Ancak şimdilik standart bir seçenek değil.
GManNickG

1
@GManNickG Sanırım @Jet, bir vektörü bir diziye dönüştürmek istiyorsanız ve diziyi kullanmanız veya yapmanız gereken size()işlevi kullanarak boyutlandırmayı planladığınızı söylüyor. Zaten belirtildiği gibi (sizin tarafınızdan) geçerli değil. Vektörü yeni yerine kullanmak iyi bir fikirdir, ancak sorunun tüm amacı bir vektörü bir diziye nasıl dönüştürebileceğinizdir. std:vectornewmallocdouble arr[v.size()]
RyanP


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

Özel dikkat gösterecektir sadece kullanımına: Bu standarda göre çalışmaları garantilidir, ancak bazı uyarılar vardır thearrayiken thevectorkapsamı içindedir.


4
... ve vektörün olmadığından emin olun empty(), aksi takdirde bu korkunç UB'yi çağırır.
sbi

13

Vektörler etkili bir şekilde derinin altındaki dizilerdir. Bir fonksiyonunuz varsa:

void f( double a[]);

şöyle diyebilirsiniz:

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

Bir vektörü gerçek bir dizi örneğine dönüştürmeniz gerekmez.


1
Sanırım f( &v[0] );son hattın için demek
istedin

10

Gelince std::vector<int> vecalmak için vec, int*, iki yöntemi kullanabilirsiniz:

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

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

Herhangi bir Tvektör türünü dönüştürmek istiyorsanız T* array, yukarıdakileri intdeğiştirin T.

Size iyi bir anlayış için yukarıdaki iki çalışmanın neden işe yaradığını göstereceğim?

std::vector aslında dinamik bir dizidir.

Ana veri üyesi aşağıdaki gibi:

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){}
    //......
}

range (start_, end_of_storage_)Vektör tahsis tüm dizi bellektir;

range(start_, finish_)Vektör kullanılan tüm dizi bellektir;

range(finish_, end_of_storage_)Yedek dizi bellektir.

Örneğin, bir vektör vec. {9, 9, 1, 2, 3, 4} olan işaretçi aşağıdaki gibidir.

resim açıklamasını buraya girin

Yani &vec[0]= başlangıç_ (adres.) (Başlangıç_ int * dizi başlığına eşdeğerdir)

In üye fonksiyonu sadece start_ dönmekc++11data()

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

2

Bunu data () yöntemini kullanarak yapabiliriz. C ++ 11 bu yöntemi sağlar.

Kod Parçacığı

#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

Eğer bir işlevi varsa, o zaman muhtemelen bu gerekir: foo(&array[0], array.size());. Eğer bir diziye ihtiyaç duyduğunuz bir duruma girmeyi başardıysanız, yeniden düzenleme yapmanız gerekir, vektörler temelde genişletilmiş dizilerdir, bunları her zaman kullanmalısınız.


-1

Bunun gibi bazı şeyler yapabilirsiniz

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]; dizi için
Sakthi Vignesh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.