Як конвертувати вектор у масив


352

Як перетворити a std::vector<double>в a double array[]?


9
Ніби не запитує, чому? Ви можете отримати доступ до вектора як масив. Що робить масив, який не має вектор?
Майкл Дорган

96
@Michael Типовий випадок використання, який я маю, використовує вектор у власному коді та потребує виклику сторонньої функції, яка займає масив
Майкл Мрозек

7
Термінологія, яку кидають, є заплутаною. Вказівник не є масивом. Чи хочемо ми вказувати на перший елемент масиву чи масив?
GManNickG

7
абсолютно реальне запитання - досить просте, легко інтерпретоване. будь ласка, знову відкрийте.
dbliss

10
"Ніби не запитує, чому?" - По-перше, неправильне використання цієї фрази. По-друге, це кровотеча очевидно, чому.
Джим Балтер

Відповіді:


533

Для цього є досить простий трюк, оскільки специфікація тепер гарантує, що вектори постійно зберігають свої елементи:

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

29
@ganuke Ви не копіюєте, ви робите вказівник, який вказує на фактичний масив, який вектор використовує всередині. Якщо ви хочете скопіювати відповідь GMan, пояснюється як
Майкл Мрозек

4
@ganuke: Що таке "масив"? Вам потрібно надати більше інформації. Яка велика картина?
GManNickG

6
@ganuke Ви цього не робите, вам просто потрібна цифра, double*яка вказує на ті самі дані. Ця відповідь відповідає саме тому випадку
Майкл Мрозек

6
@guneykayim Вектор належить цій пам’яті, ви не повинні звільняти її
Майкл Мрозек

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

148

Для чого? Вам потрібно уточнити: чи потрібен вам вказівник на перший елемент масиву чи масив?

Якщо ви викликаєте функцію API, яка очікує колишньої, ви можете зробити do_something(&v[0], v.size()), де vвектор doubles. Елементи вектора є суміжними.

В іншому випадку потрібно просто скопіювати кожен елемент:

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

Переконайтеся, що не тільки thar arrє достатньо великим, але це arrзаповнюється, або у вас є неініціалізовані значення.


15
Примітка: використовуйте v.size (), щоб отримати кількість елементів для нового масиву: подвійний arr [v.size ()];
rbaleksandar

7
@rbaleksandar: Масиви не можуть мати постійний розмір вираження.
GManNickG

@GManNickG: Це працює, але я думаю, тут є непорозуміння. Уявіть наступне: у вас є клас із купою вказівників різних типів, які мають вказувати на масиви, які невідомі в той момент, коли ви визначаєте свій клас, і які пізніше створюються, промітуючи різні вектори та використовуючи їх розмір-параметр визначити, скільки місця потрібно використовувати. Інший приклад: проста функція void arrayTest (без підпису int arrSize), яка створює в ній масив (короткий arr [arrSize];), використовуючи його параметр функції для розміру.
rbaleksandar

1
@rbaleksandar Немає непорозумінь; в C ++ 11 і попередніх розмірах масиву повинні бути інтегральні постійні вирази. Ваш приклад функції - це звичайне використання для VLA в C, але підтримується лише (нестандартним) розширенням на C ++. Це може прийти до C ++ 14, хоча: stackoverflow.com/a/17318040/87234 . Але на даний момент це просто не стандартний варіант.
GManNickG

1
@GManNickG Я думаю, що @Jet говорить, що якщо ви хочете перетворити вектор в масив, і ви маєте намір розмістити масив за допомогою size()функції, std:vectorвам потрібно буде використовувати newабо mallocзробити це. Як вже було зазначено вами, double arr[v.size()]це неправда. Використовувати вектор замість нового - це гарна ідея, але вся суть питання полягає в тому, як можна перетворити вектор у масив.
RyanP


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

Це гарантовано працювати за стандартом, проте є деякі застереження: зокрема догляду прийняти для використання тільки в thearrayтой час як thevectorв області видимості.


4
... і переконайтеся, що вектора немає empty(), інакше це призведе до жахливого UB.
sbi

13

Вектори ефективно - це масиви під шкірою. Якщо у вас є функція:

void f( double a[]);

ви можете назвати це так:

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

Вам ніколи не потрібно перетворювати вектор у фактичний екземпляр масиву.


1
Я думаю, ти мав f( &v[0] );на увазі для свого останнього рядка
Майкла Мрозека

10

Що стосується std::vector<int> vecvec, щоб отримати int*, ви можете використовувати два способи:

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

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

Якщо ви хочете , щоб перетворити будь-який тип Tвектора T* array, просто замінити вище intдо T.

Я покажу тобі, чому ці вищезгадані роботи працюють для гарного розуміння?

std::vector є по суті динамічним масивом.

Основний учасник даних, як показано нижче:

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_)це вся пам'ять масиву, яку виділяє вектор;

- range(start_, finish_)це вся пам'ять масиву, яку використовує вектор;

The range(finish_, end_of_storage_)- це резервна пам'ять масиву.

Наприклад, щодо вектора vec. який має {9, 9, 1, 2, 3, 4}, вказівник може подобатися нижче.

введіть тут опис зображення

Отже &vec[0]= start_ (адреса.) (Start_ еквівалентно int * head масиву)

У c++11 функції data()члена просто поверніть start_

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

2

Це можна зробити за допомогою методу data (). C ++ 11 забезпечує цей метод.

Знімок коду

#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

Якщо у вас є функція, то вам , ймовірно , потрібно це: foo(&array[0], array.size());. Якщо вам вдалося потрапити в ситуацію, коли вам потрібен масив, тоді вам потрібно переробляти, вектори - це в основному розширені масиви, ви завжди повинні їх використовувати.


-1

Ви можете зробити щось подібне

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]; для 2-го масиву
Sakthi Vignesh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.