STL vector与数组的互转
C++ STL库中vector素有动态数组的美誉,为什么?我想有以下几个原因:1)它能够弥补普通数组(如“int a[8]”)只能固定长度的缺陷;2)它能弥补一般堆数组(如int *p = new int[n])需要预先知道长度,并且长度不可变的缺陷。 在有些情况下,比如从文件中读取一组未知长度的float型的数据。3)相对STL中其他容器,如list,vector与数组更接
C++ STL库中vector素有动态数组的美誉,为什么?我想有以下几个原因:
1)它能够弥补普通数组(如“int a[8]”)只能固定长度的缺陷;
2)它能弥补一般堆数组(如int *p = new int[n])需要预先知道长度,并且长度不可变的缺陷。
在有些情况下,比如从文件中读取一组未知长度的float型的数据。
3)相对STL中其他容器,如list,vector与数组更接近,它内部的数据存储在一片连续的存储空间,访问效率会更高;而list是链表,数据在存储空间上不相邻。
vector的“动态数组”的美誉的另一体现是,它与数组的灵活互转。
一、数组转vector
利用vector的构造函数,可以很方便的将数组转为vector。例如:
float arrHeight[] = { 1.68,1.72,1.83,2.05,2.35,1.78,2.1,1.96 };
vector<float> vecHeight(arrHeight, arrHeight+sizeof(arrHeight)/sizeof(float));
参考官方文档:http://www.cplusplus.com/reference/vector/vector/
关于vector的构造,有如下几种:
default (1) | explicit vector (const allocator_type& alloc = allocator_type()); |
---|---|
fill (2) | explicit vector (size_type n); vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type()); |
range (3) | template <class InputIterator> vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
copy (4) | vector (const vector& x); vector (const vector& x, const allocator_type& alloc); |
move (5) | vector (vector&& x); vector (vector&& x, const allocator_type& alloc); |
initializer list (6) | vector (initializer_list<value_type> il, const allocator_type& alloc = allocator_type()); |
上述例子用的就是第三种,range构造函数。我在VS2015下进行了实验,通过查看内存,可以发现,vecHeight的数据部分的内存地址和arrHeight是相同的,也就是说,上述例子中,没有真正进行数据拷贝,这里应该是用到了“写时复制”的技术,提高了数据复制的效率。
此外,可以参考博客:http://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.html
二、vector转数组
由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可。如果仅仅是传参,无需任何操作,直接传地址即可,如果要进行数据复制,可以借用内存拷贝函数“memcpy”。例如:
float *buffer = new float[vecHeight.size()];
if (!vecHeight.empty())
{
memcpy(buffer, &vecHeight[0], vecHeight.size()*sizeof(float));
}
本段参考博客:http://nianning1981.blog.163.com/blog/static/3083014320103171299619/
三、应用建议
1,vector作为动态数组,它的实现方法是:预先分配一个内存块,当感觉不够用的时候,再分配一个更大的内存块,然后自动将之前的数据拷贝到新的内存块中。
所以,出于效率考虑,如果实现知道待存储的数据长度,可以使用resize函数开辟足够的内存,避免后续的内存拷贝。
2,如果数组的元素是字符,建议使用string,而不是vector<char>。
附两篇博文,谈vector等容器的效率问题:
http://www.cnblogs.com/smiler/p/4457622.html
http://www.cppblog.com/sailing/articles/161659.html
更多推荐
所有评论(0)