Làm cách nào để chuyển đổi a std::vector<double>
thành a double array[]
?
Làm cách nào để chuyển đổi a std::vector<double>
thành a double array[]
?
Câu trả lời:
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];
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 đó
std::vector<double> v; double* a = v.data();
Để 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())
, đó v
là một vectơ của double
s. 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.
size()
chức năng của std:vector
bạn sẽ cần sử dụng new
hoặ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.
Đối với C ++ 11 , vector.data()
sẽ thực hiện thủ thuật.
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 thearray
trong khi thevector
trong phạm vi.
empty()
, nếu không điều này sẽ gọi UB đáng sợ.
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ế.
f( &v[0] );
cho dòng cuối cùng của bạn
Để std::vector<int> vec
, vec để có được int*
, bạn có thể sử dụng hai phương pháp:
int * mảng = & vec [0];
int * Array = vec.data ();
Nếu bạn muốn chuyển đổi bất kỳ loại T
vector để 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.
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)
}
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.
#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;
}
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.
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;
}
}
}