如何将向量转换为数组
Posted
技术标签:
【中文标题】如何将向量转换为数组【英文标题】:How to convert vector to array 【发布时间】:2010-05-27 17:14:40 【问题描述】:如何将std::vector<double>
转换为double array[]
?
【问题讨论】:
有点想问为什么?您可以将向量作为数组访问。数组有什么作用而向量没有? @Michael 我的典型用例是在我自己的代码中使用向量,并且需要调用采用数组的第三方函数 被抛出的术语令人困惑。指针不是数组。我们想要一个指向数组第一个元素的指针,还是一个数组? @MichaelDorgan 难以置信,有时是必要的。例如,当作为参数传递给 CUDA 内核时 当您必须先构建 argc/argv 数组并过滤一些选项时,此功能对于指向char*
的向量特别有用。
【参考方案1】:
有一个相当简单的技巧可以做到这一点,因为规范现在 guarantees 向量连续存储它们的元素:
std::vector<double> v;
double* a = &v[0];
【讨论】:
@ganuke 您不是在复制,而是在创建一个指针,该指针指向向量在内部使用的实际数组。如果要复制GMan's answer说明如何 @ganuke:什么是“阵列”?您需要提供更多信息。大局是什么? @ganuke 你不需要,你只需要一个指向相同数据的double*
。这个答案恰好适用于这种情况
@guneykayim 向量拥有该内存,你不应该释放它
std::vector<double> v; double* a = v.data();
【参考方案2】:
为了什么?你需要澄清一下:你需要一个指向数组第一个元素的指针,还是一个数组?
如果您调用的 API 函数需要前者,您可以使用 do_something(&v[0], v.size())
,其中 v
是 double
s 的向量。向量的元素是连续的。
否则,您只需复制每个元素:
double arr[100];
std::copy(v.begin(), v.end(), arr);
确保不仅arr
足够大,而且arr
被填满,或者您有未初始化的值。
【讨论】:
注:使用v.size()获取新数组的元素个数:double arr[v.size()]; @rbaleksandar:数组不能有非常量的表达式大小。 @rbaleksandar 没有误解;在 C++11 和之前的版本中,数组大小必须是整数常量表达式。您的函数示例是 C 中 VLA 的常见用途,但仅受 C++ 中的(非标准)扩展支持。不过它可能会出现在 C++14 中:***.com/a/17318040/87234。但截至目前,这根本不是标准选项。 注意:使用“malloc”或“new”动态分配大小为v.size()的内存,然后全部复制到那里。并且记住当你不再需要它时“free()”或“delete”指针。 @GManNickG 我认为@Jet 是说如果你想将一个向量转换为一个数组,并且你打算使用std:vector
的size()
函数来调整数组的大小,你需要使用new
或malloc
来做到这一点。正如(您)已经指出的那样,double arr[v.size()]
无效。使用 vector 代替 new 是个好主意,但问题的关键在于如何将向量转换为数组。【参考方案3】:
对于C++11,vector.data()
可以解决问题。
【讨论】:
注意:它不复制vector的数据,它只存储指向vector内部使用的实际数组的指针。【参考方案4】:vector<double> thevector;
//...
double *thearray = &thevector[0];
这保证按标准工作,但有一些警告:特别注意只使用 thearray
而 thevector
在范围内。
【讨论】:
...并确保向量不是empty()
,否则会调用可怕的UB。
(未定义行为)【参考方案5】:
对于std::vector<int> vec
, vec 获取int*
,可以使用两种方法:
int* arr = &vec[0];
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_)
是向量使用的所有数组内存;
range(finish_, end_of_storage_)
是备份阵列内存。
例如,对于向量 vec。其中有 9, 9, 1, 2, 3, 4 的指针可能如下所示。
所以&vec[0]
= start_(地址。)(start_相当于int*数组头)
在c++11
data()
成员函数中只返回start_
pointer data()
return start_; //(equivalent to `value_type*`, array head)
【讨论】:
【参考方案6】:向量实际上是皮肤下的数组。如果你有一个函数:
void f( double a[]);
你可以这样称呼它:
vector <double> v;
v.push_back( 1.23 )
f( &v[0] );
您永远不需要将向量转换为实际的数组实例。
【讨论】:
我认为你的最后一行是f( &v[0] );
【参考方案7】:
std::vector<double> vec;
double* arr = vec.data();
【讨论】:
【参考方案8】:我们可以使用 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;
【讨论】:
【参考方案9】:如果你有一个函数,那么你可能需要这个:foo(&array[0], array.size());
。如果你设法遇到需要数组的情况,那么你需要重构,向量基本上是扩展数组,你应该总是使用它们。
【讨论】:
【参考方案10】:你可以做一些这样的事情
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];对于二维数组以上是关于如何将向量转换为数组的主要内容,如果未能解决你的问题,请参考以下文章