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

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

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

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对象中存储简单分配器的任何数据。

Bash
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:

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

Bash
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-

相关推荐

在 Linux 系统中安装 Redis 的详细步骤

以下是在Linux系统中安装Redis的详细步骤,支持通过包管理器安装(简单快捷)和源码编译安装(获取最新版本)两种方式:方法1:使用包管理器安装(推荐新手)适用于Ubuntu/De...

在Linux系统上安装Redis集群的详细步骤

以下是在Linux系统上安装Redis集群的详细步骤,基于Redis6.x+版本,采用三主三从(6个节点)的典型配置模式:1.安装前准备环境要求系统:Ubuntu/CentOS等主流Linux发行...

Linux入门使用教程

Linux入门一、初始化配置CentOS初始化安装在开始熟悉Linux操作命令之前,我们必须先搭建好Linux操作系统环境,我们这里选用的是Linux的发行版本CentOS7,在安装好CentOS操作...

06新手学习:Linux入门级命令教程

1、开启终端问题:什么是终端(Terminal)答:Linux操作系统中用于输入命令的位置打开后,效果如下图所示:2、Linux命令格式什么是Linux的命令?答:就是指在Linux终端(命令行)...

【笔记】windows10安装linux双系统教程(可能是现今最简单方法)

这周测试成功了大牛漂移菌教的树莓派系统镜像的压缩方法(【树莓派】小空间树莓派镜像系统备份方法img镜像文件压缩方法),虚拟机下备份镜像不太方便,无论是存储空间还是读卡操作都不方便。所以打算装个linu...

网络安全工程师:小白是如何让Kali Linux操作系统从U盘成功启动

一、背景介绍作为一名渗透测试工作人员(或者小白),在我们的日常工作或者学习中,我们不可能时时刻刻将自己的个人电脑(安装好KaliLinux的个人主机)带在身边,当我们没有带自己的个人电脑而需要进行渗...

Linux配置ip地址的两种方法

Linux配置ip地址的两种方法,实验环境为centos7.6方法1:nmcli工具配置(centos7以下版本不支持该方法)第一步,通过nmcliconnection查看网卡名称[root@lo...

Linux man 命令使用教程

简介man=manual(手册)命令用来查看Linux系统命令、函数、配置文件、系统调用等的官方文档。几乎所有标准程序和工具都有对应的man手册。基本语法man[options][s...

Linux程序安装与管理指南

在Linux系统中,安装和管理程序主要通过包管理器和手动编译安装两种主要方式实现。以下是详细的操作指南,涵盖常见发行版(如Ubuntu/Debian、CentOS/RHEL、Fedora等)的用法。一...

零基础保姆级教程!手把手教你免费玩转Linux安装+学习环境搭建!

前期准备安装VMware虚拟机首先你要安装VMware虚拟机,如果你还不知道VMware是什么可以去看我的VMware相关教程,里面有详细解答检查V-CPU虚拟化是否开启当我们在虚拟机安装系统的...

网络安全工程师:小白如何使用Kali Linux生成木马后门并实现免沙

1.背景介绍msfvenom是msfpayload和msfencode的结合体,可利用msfvenom生成木马程序,并在目标机上执行,在本地监听上线,在黑客圈子,这款工具略有名气。本次教程是Msfve...

Linux详解系列一:如何安装系统及客户端工具的使用

Linux是一种开放源码的操作系统,和Windows不同的是,由于其具有开源,稳定性强,安全,多用户操作等特点,它的使用场景非常广泛,比如企业中所使用的服务器中的操作系统,以及移动端的Andr...

4种方案供你选,微软发布《如何下载和安装Linux》教程

IT之家10月14日消息,微软近日发布了一个教程指南《如何下载和安装Linux》,介绍了使用WSL、本地安装、本地虚拟机和云端虚拟机4种方案。该指南重点介绍了用户在PC上运行Li...

嵌入式Linux开发教程:Linux Shell

本章重点介绍Linux的常用操作和命令。在介绍命令之前,先对Linux的Shell进行了简单介绍,然后按照大多数用户的使用习惯,对各种操作和相关命令进行了分类介绍。对相关命令的介绍都力求通俗易懂,都给...

Linux基础手把手教学:使用22.04系统

Linux基础手把手教学:使用Ubuntu22.04系统。1.这节来讲一下下边的目录结构,因为只有清楚了解linux下边的目录结构,才能很方便地进行操作。linux下边的目录结构较为简单...