Làm thế nào để chuyển đổi vector thành mảng


352

Làm cách nào để chuyển đổi a std::vector<double>thành a double array[]?


9
Kinda cầu xin câu hỏi tại sao? Bạn có thể truy cập một vectơ như một mảng. Một mảng làm gì mà một vectơ không có?
Michael Dorgan

96
@Michael Trường hợp sử dụng điển hình mà tôi có đang sử dụng một vectơ trong mã của riêng tôi và cần gọi một hàm của bên thứ ba có một mảng
Michael Mrozek

7
Thuật ngữ bị ném xung quanh là khó hiểu. Một con trỏ không phải là một mảng. Chúng ta muốn một con trỏ đến phần tử đầu tiên của một mảng, hay một mảng?
GManNickG

7
hoàn toàn là một câu hỏi thực sự - một câu hỏi khá đơn giản, dễ hiểu. vui lòng mở lại
dbliss 7/12/2015

10
"Kinda cầu xin câu hỏi tại sao?" - Đầu tiên, sử dụng sai cụm từ đó. Thứ hai, nó chảy máu rõ ràng tại sao.
Jim Balter

Câu trả lời:


533

Có một mẹo khá đơn giản để làm như vậy, vì thông số kỹ thuật hiện đảm bảo các vectơ lưu trữ các phần tử của chúng liền nhau:

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

29
@ganuke Bạn không sao chép, bạn đang tạo một con trỏ trỏ đến mảng thực tế mà vectơ đang sử dụng bên trong. Nếu bạn muốn sao chép câu trả lời của GMan, hãy giải thích như thế nào
Michael Mrozek

4
@ganuke: "mảng" là gì? Bạn cần cung cấp thêm thông tin. Bức tranh lớn là gì?
GManNickG

6
@ganuke Bạn không cần, bạn chỉ cần một double*điểm trỏ đến cùng một dữ liệu. Câu trả lời này hoạt động chính xác cho trường hợp đó
Michael Mrozek

6
@guneykayim Vectơ sở hữu bộ nhớ đó, bạn không nên giải phóng nó
Michael Mrozek

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

148

Để làm gì? Bạn cần làm rõ: Bạn có cần một con trỏ đến phần tử đầu tiên của một mảng hoặc một mảng không?

Nếu bạn đang gọi một hàm API mong đợi cái trước, bạn có thể làm do_something(&v[0], v.size()), đó vlà một vectơ của doubles. Các yếu tố của một vectơ là liên tục.

Nếu không, bạn chỉ cần sao chép từng phần tử:

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

Đảm bảo không chỉ thar arrđủ lớn mà còn arrđược lấp đầy hoặc bạn có các giá trị chưa được khởi tạo.


15
Lưu ý: sử dụng v.size () để lấy số phần tử cho mảng mới: double Array [v.size ()];
rbaleksandar

7
@rbaleksandar: Mảng không thể có kích thước biểu thức không cố định.
GManNickG

@GManNickG: Nó hoạt động nhưng tôi nghĩ có một số hiểu lầm ở đây. Hãy tưởng tượng như sau: bạn có một lớp với một loạt các con trỏ thuộc nhiều loại khác nhau phải trỏ đến các mảng, không biết tại thời điểm bạn xác định lớp của mình và sau này được tạo bằng cách xóa các vectơ khác nhau và sử dụng tham số kích thước của chúng để xác định bao nhiêu không gian sẽ được sử dụng. Một ví dụ khác: một hàm đơn giản void ArrayTest (unsign int ArraySize), tạo ra một mảng (short Array [ArraySize];) trong đó bằng cách sử dụng tham số hàm của nó cho kích thước.
rbaleksandar

1
@rbaleksandar Không hiểu lầm; trong C ++ 11 và trước đó, kích thước mảng phải là biểu thức hằng tích phân. Ví dụ về chức năng của bạn là một cách sử dụng phổ biến cho các VLA trong C, nhưng chỉ được hỗ trợ bởi phần mở rộng (không chuẩn) trong C ++. Nó có thể đến với C ++ 14 mặc dù: stackoverflow.com/a/17318040/87234 . Nhưng như bây giờ, nó đơn giản không phải là một lựa chọn tiêu chuẩn.
GManNickG

1
@GManNickG Tôi nghĩ rằng @Jet đang nói rằng nếu bạn muốn chuyển đổi một vectơ thành một mảng và bạn có ý định kích thước mảng bằng cách sử dụng size()chức năng của std:vectorbạn sẽ cần sử dụng newhoặc mallocđể làm điều đó. Như nó đã được chỉ ra (bởi bạn) double arr[v.size()]không hợp lệ. Sử dụng vectơ thay cho mới là một ý tưởng tốt, nhưng toàn bộ điểm của câu hỏi là làm thế nào bạn có thể chuyển đổi một vectơ thành một mảng.
RyanP


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

Điều này được đảm bảo để hoạt động theo tiêu chuẩn, tuy nhiên có một số lưu ý: đặc biệt chú ý chỉ sử dụng thearraytrong khi thevectortrong phạm vi.


4
... Và chắc chắn rằng vectơ không empty(), nếu không điều này sẽ gọi UB đáng sợ.
sbi

13

Các vectơ có hiệu quả là các mảng dưới da. Nếu bạn có một chức năng:

void f( double a[]);

bạn có thể gọi nó như thế này:

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

Bạn không cần phải chuyển đổi một vectơ thành một thể hiện mảng thực tế.


1
Tôi nghĩ bạn có ý nghĩa f( &v[0] );cho dòng cuối cùng của bạn
Michael Mrozek

10

Để std::vector<int> vec, vec để có được int*, bạn có thể sử dụng hai phương pháp:

  1. int * mảng = & vec [0];

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

Nếu bạn muốn chuyển đổi bất kỳ loại Tvector để T* array, chỉ cần thay thế ở trên intđể T.

Tôi sẽ chỉ cho bạn tại sao hai công việc trên, để hiểu rõ?

std::vector là một mảng động về cơ bản.

Thành viên dữ liệu chính như sau:

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

Tất range (start_, end_of_storage_)cả là bộ nhớ mảng mà vector phân bổ;

Đây range(start_, finish_)là tất cả các bộ nhớ mảng mà vectơ sử dụng;

Bộ range(finish_, end_of_storage_)nhớ mảng dự phòng.

Ví dụ, như một vec tơ. trong đó có {9, 9, 1, 2, 3, 4} là con trỏ có thể thích bên dưới.

nhập mô tả hình ảnh ở đây

So &vec[0]= start_ (address.) (Start_ tương đương với int * mảng đầu)

Trong c++11 các data()hàm thành viên chỉ trả start_

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

2

Chúng ta có thể làm điều này bằng cách sử dụng phương thức data (). C ++ 11 cung cấp phương pháp này.

Đoạn mã

#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

Nếu bạn có một chức năng, thì có lẽ bạn cần điều này : foo(&array[0], array.size());. Nếu bạn quản lý để đi vào một tình huống mà bạn cần một mảng thì bạn cần cấu trúc lại, các vectơ là các mảng cơ bản được mở rộng, bạn nên luôn luôn sử dụng chúng.


-1

Bạn có thể làm một số thứ như thế này

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]; cho mảng 2d
Sakthi Vignesh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.