百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

C++|内置数组、STL array、STL vector

xsobi 2024-11-24 00:29 1 浏览

T[N]

Built-in array: a fixed-size contiguously allocated sequence of N elements of type T; implicitly converts to a T*

内置数组:固定大小的连续分配的T型N个元素序列;隐式转换为T*

array<T,N>

A fixed-size contiguously allocated sequence of N elements of type T; like the built-in array, but with most problems solved

T型N个元素的固定大小连续分配序列;与内置数组类似,但大多数问题都已解决

A vector is a sequence of elements of a given type. The elements are stored contiguously in memory. A typical implementation of vector will consist of a handle holding pointers to the first element, one-past-the-last element, and one-past-the-last allocated space (§13.1) (or the equivalent information represented as a pointer plus offsets):

vector是给定类型的元素序列。元素连续存储在存储器中。vector的典型实现将由一个句柄组成,该句柄持有指向第一个元素的指针,一个指针位于最后一个元素之后,一个位于最后分配的空间之后(或表示为指针加偏移的等效信息):

In addition, it holds an allocator (here, alloc), from which the vector can acquire memory for its elements. The default allocator uses new and delete to acquire and release memory. Using a slightly advanced implementation technique, we can avoid storing any data for simple allocators in a vector object.

此外,它还包含一个分配器(这里是alloc),vector可以从中获取元素的内存。默认分配器使用new和delete来获取和释放内存。使用稍微先进的实现技术,我们可以避免在vector对象中存储简单分配器的任何数据。

template<typename T>
class Vector {
       allocator<T> alloc;    // standard-library allocator of space for Ts
       T* elem;                     // pointer to first element
       T* space;                   // pointer to first unused (and uninitialized) slot
       T* last;                       // pointer to last slot
public:
       // ...
       int size() const { return space-elem; }            // number of elements
       int capacity() const { return last-elem; }        // number of slots available for elements
       // ...
       void reserve(int newsz);                         // increase capacity() to newsz
       // ...
       void push_back(const T& t);                 // copy t into Vector
       void push_back(T&& t);                         // move t into Vector
};

STL array, and tuple elements are contiguously allocated; list and map are linked structures.

StL array和tuple元素被连续分配;list和map是链接结构。

An STL array, defined in <array>, is a fixed-size sequence of elements of a given type where the number of elements is specified at compile time. Thus, an array can be allocated with its elements on the stack, in an object, or in static storage. The elements are allocated in the scope where the array is defined. An array is best understood as a built-in array with its size firmly attached, without implicit, potentially surprising conversions to pointer types, and with a few convenience functions provided. There is no overhead (time or space) involved in using an array compared to using a built-in array.

在<array>中定义的STL array是给定类型的元素的固定大小序列,其中元素的数量在编译时指定。因此,可以在堆栈、对象或静态存储中为数组分配元素。元素在定义数组的范围内分配。STL array最好理解为一个内置数组(built-in array),其大小固定,没有隐含的、可能令人惊讶的指针类型转换,并且提供了一些方便的函数。与使用内置数组相比,使用STL array不需要任何开销(时间或空间)。

An array does not follow the “handle to elements” model of STL containers. Instead, an array directly contains its elements. It is nothing more or less than a safer version of a built-in array.

STL array不遵循STL容器的“句柄到元素”模型。相反,数组直接包含其元素。它或多或少是内置array的一个更安全的版本。

This implies that an array can and must be initialized by an initializer list:

这意味着数组可以也必须由初始值设定项列表初始化:

array<int,3> a1 = {1,2,3};

The number of elements in the initializer must be equal to or less than the number of elements specified for the array.

初始值设定项中的元素数必须等于或小于为数组指定的元素数。

The element count is not optional, the element count must be a constant expression, the number of elements must be positive, and the element type must be explicitly stated:

元素计数不是可选的,元素计数必须是常量表达式,元素数必须为正数,并且必须明确声明元素类型:

void f(int n)
{
    array<int> a0 = {1,2,3};                      // error size not specified
    array<string,n> a1 = {"John's", "Queens' "};  // error: size not a constant expression
    array<string,0> a2;                           // error: size must be positive
    array<2> a3 = {"John's", "Queens' "};         // error: element type not stated
    // ...
}

If you need the element count to be a variable, use vector.

如果您需要元素计数为变量,请使用vector。

When necessary, an STL array can be explicitly passed to a C-style function that expects a pointer. For example:

必要时,可以将STL array显式传递给需要指针的C样式函数。例如:

void f(int* p, int sz);         // C-style interface
void g()
{
        array<int,10> a;
         f(a,a.size());             // error: no conversion
         f(a.data(),a.size());      // C-style use
         auto p = find(a,777);      // C++/STL-style use (a range is passed)
         // ...
}

Why would we use an STL array when vector is so much more flexible? An array is less flexible so it is simpler. Occasionally, there is a significant performance advantage to be had by directly accessing elements allocated on the stack rather than allocating elements on the free store, accessing them indirectly through the vector (a handle), and then deallocating them. On the other hand, the stack is a limited resource (especially on some embedded systems), and stack overflow is nasty. Also, there are application areas, such as safety-critical real-time control, where free store allocation is banned. For example, use of delete may lead to fragmentation or memory exhaustion.

当STL vector如此灵活时,我们为什么要使用STL array?STL array不太灵活,因此更简单。有时,直接访问堆栈上分配的元素,而不是在空闲存储(堆)上分配元素,通过vector(句柄)间接访问它们,然后释放它们,会带来显著的性能优势。另一方面,堆栈是一种有限的资源(尤其是在一些嵌入式系统上),并且堆栈溢出非常严重。此外,还有一些应用领域,如安全关键型实时控制,禁止空闲存储(堆)分配。例如,使用delete可能会导致碎片化或内存耗尽。

Why would we use an STL array when we could use a built-in array? An array knows its size, so it is easy to use with standard-library algorithms, and it can be copied using =. For example:

当我们可以使用内置数组时,为什么要使用STL array?STL array知道它的大小,因此它很容易与标准库算法一起使用,并且可以使用操作符“=”复制它。例如:

array<int,3> a1 = {1, 2, 3 };
auto a2 = a1;     // copy
a2[1] = 5;
a1 = a2;              // assign

However, the main reason to prefer STL array is that it saves me from surprising and nasty conversions to pointers. Consider an example involving a class hierarchy:

然而,更喜欢数组的主要原因是,它避免了对指针的令人惊讶和讨厌的转换。考虑一个涉及类层次结构的示例:

void h()
{
    Circle a1[10];
    array<Circle,10> a2;
    // ...
    Shape* p1 = a1;       // OK: disaster waiting to happen
    Shape* p2 = a2;       // error: no conversion of array<Circle,10> to Shape* (Good!)
    p1[3].draw();         // disaster
}

The “disaster” comment assumes that sizeof(Shape)<sizeof(Circle), so subscripting a Circle[] through a Shape* gives a wrong offset. All standard containers provide this advantage over built-in arrays.

“disaster”注释假定sizeof(Shape)<size of(Circle),因此通过Shape*下标Circle[]给出了错误的偏移量。与内置数组相比,所有标准容器都提供了这一优势。

ref

Bjarne Stroustrup, A Tour of C++ Third Edition

-End-

相关推荐

js向对象中添加元素(对象,数组) js对象里面添加元素

一、添加一个元素对象名["属性名"]=值(值:可以是一个值,可以是一个对象,也可以是一个数组)这样添加进去的元素,就是一个值或对象或数组...

JS小技巧,如何去重对象数组?(一)

大家好,关于数组对象去重的业务场景,想必大家都遇到过类似的需求吧,这对这样的需求你是怎么做的呢。下面我就先和大家分享下如果是基于对象的1个属性是怎么去重实现的。方法一:使用.filter()和....

「C/C++」之数组、vector对象和array对象的比较

数组学习过C语言的,对数组应该都不会陌生,于是这里就不再对数组进行展开介绍。模板类vector模板类vector类似于string,也是一种动态数组。能够在运行阶段设置vector对象的长度,可以在末...

如何用sessionStorage保存对象和数组

背景:在工作中,我将[{},{}]对象数组形式,存储到sessionStorage,然后ta变成了我看不懂的形式,然后我想取之用之,发现不可能了~记录这次深刻的教训。$clickCouponIndex...

JavaScript Array 对象 javascript的array对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

JavaScript中的数组Array(对象) js array数组

1:数组Array:-数组也是一个对象-数组也是用来存储数据的-和object不同,数组中可以存储一组有序的数据,-数组中存储的数据我们称其为元素(element)-数组中的每一个元素都有一...

数组和对象方法&amp;数组去重 数组去重的5种方法前端

列举一下JavaScript数组和对象有哪些原生方法?数组:arr.concat(arr1,arr2,arrn);--合并两个或多个数组。此方法不会修改原有数组,而是返回一个新数组...

C++ 类如何定义对象数组?初始化数组?linux C++第43讲

对象数组学过C语言的读者对数组的概念应该很熟悉了。数组的元素可以是int类型的变量,例如int...

ElasticSearch第六篇:复合数据类型-数组,对象

在ElasticSearch中,使用JSON结构来存储数据,一个Key/Value对是JSON的一个字段,而Value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个JSON...

第58条:区分数组对象和类数组对象

示例设想有两个不同类的API。第一个是位向量:有序的位集合varbits=newBitVector;bits.enable(4);bits.enable([1,3,8,17]);b...

八皇后问题解法(Common Lisp实现)

如何才能在一张国际象棋的棋盘上摆上八个皇后而不致使她们互相威胁呢?这个著名的问题可以方便地通过一种树搜索方法来解决。首先,我们需要写一个函数来判断棋盘上的两个皇后是否互相威协。在国际象棋中,皇后可以沿...

visual lisp修改颜色的模板函数 怎么更改visual studio的配色

(defunBF-yansemokuai(tuyuanyanse/ss)...

用中望CAD加载LISP程序技巧 中望cad2015怎么加载燕秀

1、首先请加载lisp程序,加载方法如下:在菜单栏选择工具——加载应用程序——添加,选择lisp程序然后加载,然后选择添加到启动组。2、然后是添加自定义栏以及图标,方法如下(以...

图的深度优先搜索和广度优先搜索(Common Lisp实现)

为了便于描述,本文中的图指的是下图所示的无向图。搜索指:搜索从S到F的一条路径。若存在,则以表的形式返回路径;若不存在,则返回nil。...

两个有助于理解Common Lisp宏的例子

在Lisp中,函数和数据具有相同的形式。这是Lisp语言的一个重大特色。一个Lisp函数可以分析另一个Lisp函数;甚至可以和另一个Lisp函数组成一个整体,并加以利用。Lisp的宏,是实现上述特色的...