如何将向量转换为数组


352

如何将a转换std::vector<double>为a double array[]


9
Kinda提出了为什么的问题?您可以将向量作为数组访问。数组不执行向量的作用是什么?
Michael Dorgan

96
@Michael我典型的用例是在自己的代码中使用向量,并且需要调用需要数组的第三方函数
Michael Mrozek 2010年

7
所使用的术语令人困惑。指针不是数组。我们是否需要一个指向数组第一个元素或数组的指针?
GManNickG 2010年

7
绝对是一个真实的问题-也是一个简单易懂的问题。请重新打开。
dbliss 2015年

10
“金田乞求为什么要问这个问题?” -首先,滥用该短语。其次,明显的原因是出血。
Jim Balter

Answers:


533

有一个相当简单的技巧,因为此规范现在保证向量可以连续存储其元素:

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

29
@ganuke您没有在复制,而是在创建一个指向向量在内部使用的实际数组的指针。如果您想复制GMan的答案,请解释如何
Michael Mrozek 2010年

4
@ganuke:什么是“数组”?您需要提供更多信息。总体情况如何?
GManNickG

6
@ganuke不需要,您只需要double*指向相同数据的a即可。这个答案适用于正是这种情况下
迈克尔Mrozek

6
@guneykayim矢量拥有该内存,您不应该释放它
Michael Mrozek 2014年

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

148

做什么的?您需要澄清:您是否需要指向数组第一个元素或数组的指针?

如果要调用期望使用前者的API函数,则可以执行do_something(&v[0], v.size()),其中v是的向量double。向量的元素是连续的。

否则,您只需要复制每个元素:

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

确保不仅thar arr足够大,而且已经arr装满,或者您具有未初始化的值。


15
注意:使用v.size()获取新数组的元素数:double arr [v.size()];
rbaleksandar

7
@rbaleksandar:数组不能具有非恒定的表达式大小。
GManNickG 2013年

@GManNickG:可以,但是我认为这里有些误解。想象一下:您有一个带有一堆必须指向数组的各种类型的指针的类,这些指针在您定义类时不为人所知,并且稍后通过刷新各种向量并使用其大小参数来创建确定要使用多少空间。另一个示例:一个简单的函数void arrayTest(unsigned int arrSize),该函数通过使用其函数参数作为大小在其中创建一个数组(短arr [arrSize];)。
rbaleksandar

1
@rbaleksandar不要误会;在C ++ 11及更低版本中,数组大小必须是整数常量表达式。函数示例是C中VLA的常用用法,但仅受C ++(非标准)扩展支持。它可能会出现在C ++ 14中:stackoverflow.com/a/17318040/87234。但是到目前为止,它根本不是标准选项。
GManNickG 2013年

1
@GManNickG我认为@Jet是说,如果您要将向量转换为数组,并且打算使用的size()功能来调整数组的大小,则std:vector需要使用newmalloc这样做。正如您已经指出的那样,这double arr[v.size()]是无效的。使用vector代替new是一个好主意,但是问题的关键是如何将vector转换为数组。
RyanP


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

这是保证该标准的工作,但也有一些注意事项:特别注意只使用thearray,而thevector在范围内。


4
...并确保向量不是empty(),否则将调用可怕的UB。
2010年

13

向量实际上是皮肤下的数组。如果具有功能:

void f( double a[]);

您可以这样称呼它:

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

您永远不需要将向量转换为实际的数组实例。


1
我认为您的意思f( &v[0] );是最后一行
Michael Mrozek 2010年

10

对于std::vector<int> vecvec int*,可以使用两种方法:

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

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

如果要将任何类型的T矢量转换为T* array,只需将以上内容替换intT

我将向您展示为什么上述两项有效,以取得很好的理解?

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,2,3,4}是指针的对象可能如下所示。

在此处输入图片说明

所以&vec[0]= start_(address。)(start_等效于int *数组头)

c++11data()成员函数只返回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;
}

2
std::vector<double> vec;
double* arr = vec.data();

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]; 二维阵列
Sakthi Vignesh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.