(delphi11最新学习资料) Object Pascal 学习笔记---第5章第1节(动态数组)

5.1.4 动态数组

​ 在传统的Pascal中,数组的大小是固定的,并且在声明数据类型时限制了元素的数量。然而,Object Pascal支持动态数组的直接和本地实现。

注解:“直接实现动态数组” 与使用指针和动态内存分配来获得类似效果的方法截然不同… 后者代码非常复杂且容易出错。 顺便说一句,动态数组是大多数现代编程语言中唯一的一种结构形式。

​ 动态数组是动态分配的,并进行引用计数(使得参数传递更快,因为只传递引用,而不是完整数组的副本)。当您完成使用数组时,可以通过将其变量设置为nil或将长度设置为零来清除数组,由于动态数组是引用计数的,编译器将自动释放内存。请注意,这仅适用于数组项使用的内存:如果数组保存对其他位置内存的引用(如对象引用),您需要确保在释放数组本身之前清理这些对象使用的内存。

​ 使用动态数组时,您可以声明一个数组类型而不指定元素的数量,然后使用SetLength过程设置数组的大小:

varArray1: array of Integer;begin// 这将导致运行时范围检查错误// Array1[0] := 100;SetLength(Array1, 10);Array1[0] := 100; // 这是可以的
end;

​ 在为数组设定长度并在堆上分配所需的内存之前,你不能使用数组。如果你这样做,要么会出现范围检查错误(如果相应的编译器选项处于激活状态),要么会在 Windows 平台上出现访问违规(Access Violation),或者在其他平台上出现类似的内存访问错误。SetLength 调用会将所有的值设置为零。数组初始化以后,你就可以立即开始读写数组值,而不必担心内存错误(除非超越了数组边界)。

​ 如果确实需要显式分配内存,你也不必直接释放内存。在上面的代码片段中,当代码结束且 Array1 变量退出作用域时,编译器会自动释放其内存(在本例中是已分配的 10 个整数)。因此,虽然可以将动态数组变量赋值为 nil 或调用 SetLength 时赋值为 0,但一般不需要这样做(也很少这样做)。

​ 请注意,SetLength 过程也可以用来调整数组的大小,如果要增大数组,则不会丢失当前的内容;如果要缩小数组,则会丢失一些元素。由于在最初的 SetLength 调用中只指定了数组的元素个数,动态数组的索引总是从 0 开始,直到元素个数减 1。换句话说,动态数组不支持经典静态 Pascal 数组的两个特性:非零低限和非整数索引。同时,动态数组与大多数基于 C 语法的语言中数组的工作方式更为相像。

​ 要查询动态数组的当前大小,与静态数组一样,你可以使用 Length、High 和 Low 函数。但是,对于动态数组,Low 总是返回 0,而 High 总是返回长度减 1。这意味着,对于一个空数组,High 返回-1(仔细想想,这是一个奇怪的值,因为它比 Low 返回的值低)。

​ 因此,在 DynArray 示例中,我使用自适应循环从动态数组中填充和提取信息。这是类型和变量定义:

typeTIntegersArray = array of Integer;varIntArray1: TIntegersArray;

​ 使用以下循环,为数组分配内存并用匹配索引的值填充:

varI: Integer;beginSetLength(IntArray1, 20);for I := Low(IntArray1) to High(IntArray1) doIntArray1[I] := I;
end;

​ 第二个按钮的代码既显示每个值又计算平均值,类似于先前示例中的代码,但包含在一个循环中:

varI: Integer;Total: Integer;beginTotal := 0;for I := Low(IntArray1) to High(IntArray1) dobeginInc(Total, IntArray1[I]);Show(I.ToString + ': ' + IntArray1[I].ToString);end;Show('Average: ' + (Total / Length(IntArray1)).ToString);
end;

​ 这段代码的输出是相当明显的(大部分被省略):

0: 0
1: 1
2: 2
3: 3
...
17: 17
18: 18
19: 19
Average: 9.5

​ 除了Length、SetLength、Low和High之外,还有其他一些常见的过程可用于数组,比如Copy函数,它允许您复制数组的一部分(或全部)。请注意,您还可以将一个数组从一个变量分配给另一个变量,但在这种情况下,您不是在进行完全复制,而是使两个变量引用相同的内存中的同一个数组。

​ 仅在DynArray示例的最后部分中有略微复杂的代码,它以两种不同的方式将一个数组复制到另一个数组:

  • 使用Copy函数,该函数在新的数据结构中使用单独的内存区域复制数组数据
  • 使用赋值运算符,它实际上创建了一个别名,即一个新变量,引用相同的内存中的相同数组

​ 在这一点上,如果您修改新数组的元素之一,您将会影响原始版本,或者根据复制的方式而不影响它。这是完整的代码:

varIntArray2: TIntegersArray;IntArray3: TIntegersArray;begin// 别名IntArray2 := IntArray1;// 单独的复制IntArray3 := Copy(IntArray1, Low(IntArray1), Length(IntArray1));// 修改项目IntArray2[1] := 100;IntArray3[2] := 100;// 检查每个数组的值Show(Format('[%d] %d -- %d -- %d', [1, IntArray1[1], IntArray2[1], IntArray3[1]]));Show(Format('[%d] %d -- %d -- %d', [2, IntArray1[2], IntArray2[2], IntArray3[2]]));
end;

您将得到的输出如下:

[1] 100 -- 100 -- 1
[2] 2 -- 2 -- 100

​ 对IntArray2的更改会波及到IntArray1,因为它们只是对同一物理数组的两个引用;对IntArray3的更改是独立的,因为它有数据的独立副本。

动态数组的本地操作

​ 动态数组在Delphi XE7中引入了对常量数组的赋值和连接的支持。以下是一个示例,演示了这些操作:

varDI: array of Integer;I: Integer;beginDI := [1, 2, 3];       // 初始化DI := DI + DI;         // 连接DI := DI + [4, 5];      // 混合连接for I in DI dobeginShow(I.ToString);end;
end;

​ 注意此代码中使用for-in循环遍历数组元素,这是DynArrayConcat示例的一部分。这些数组可以基于任何数据类型,从简单的整数到记录和类。

​ 除了赋值和连接之外,还可以在动态数组上使用对字符串常见的Insert和Delete等函数。

​ 以下是使用Insert和Delete的示例:

varDI: array of Integer;I: Integer;beginDI := [1, 2, 3, 4, 5, 6];Insert([8, 9], DI, 4);Delete(DI, 2, 1);  // 删除第三个项目(zero-based index)
end;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/681514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS笔记三:话题

目录 简要介绍 ROS话题通信机制的一些核心概念和流程: 话题通信的流程如下 ROS常见的topic命令行指令 发布话题 1.创建ROS节点并初始化 2.创建话题发布者 3.创建消息实例并设置内容 4.将消息发布出去 5.保持节点运行 订阅话题 初始化ROS节点和创建NodeHan…

PMP考试之20240214

1、你同时管理着公司的六个项目。两个项目属于类似类型,而其他四个项目则完全不同。你的职位是? A.项目组合经理 B.项目集经理 C.项目经理 D.项目协调员 答案:A 解析:在项目组合管理中,一组相关或非相关的计划和…

二次元自适应动态引导页

源码介绍 二次元自适应动态引导页,HTMLJSCSS,记事本修改,上传到服务器即可,也可以本地双击index.html查看效果 下载地址 https://wfr.lanzout.com/isRem1o7bfcb

MockServer 服务框架设计

大部分现有的 mock 工具只能满足 HTTP 协议下简单业务场景的使用。但是面对一些复杂的业务场景就显得捉襟见肘,比如对 socket 协议的应用进行 mock,或者对于支付接口的失败重试的定制化 mock 场景。 为解决上述问题,霍格沃兹测试学院设计并研…

零基础学编程怎么入手,中文编程工具构件箱之多页面板构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手,中文编程工具构件箱之多页面板构件用法教程,系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下: 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ …

回乡后发现大家的消费水平都在升级

今天大年初四,来湖南第7天。 大年初四走亲戚,到城里姨妈家做客,我惊讶地发现,这里的消费风向正在发生一场悄然的变革。 以往,我认为大城市的消费水平代表着潮流和品质,然而这次我却发现小城市的消费观念正在…

re:从0开始的CSS之旅 14. 显示模式的切换

1. 两个属性 display 属性可以用于转换元素的显示模式 可选值: block 转换为块元素 inline 转换为行内元素 inline-block 转换为行内块元素 none 不显示元素,并且不占用元素的位置 visibility 属性用于设置元素是否显示 可选值: visible 显示…

文档类图像的智能识别,文档分类自定义分类器

文档类图像的智能识别是利用人工智能技术对文档图像进行自动识别和信息提取的过程。在实际应用中,文档分类是文档类图像识别的一个重要环节,而自定义分类器则可以提高文档分类的准确性和适应性。本文将介绍文档分类自定义分类器的相关概念和方法。 …

springboot/ssm知名作家信息管理系统Java文学作品展示管理系统

springboot/ssm知名作家信息管理系统Java文学作品展示管理系统 开发语言:Java 框架:springboot(可改ssm) vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.…

下一代块存储重新定义任务关键型存储架构

HPE 宣布全面推出基于 HPE Alletra Storage MP 构建的 HPE GreenLake for Block Storage 第 3 版,提供业界首款分解式横向扩展块存储,并提供 100% 数据可用性保证。这种独特的块存储产品由共享一切存储架构提供支持,并通过 HPE GreenLake 云平…

智能门锁代码实现之连接硬件的步骤

准备硬件和开发环境:确保你拥有所需的硬件(如微控制器、门锁控制电路、通信接口等),并设置好 C 语言的开发环境。对于 Arduino 等开源硬件平台,你可能需要安装特定的 IDE(集成开发环境)和驱动程…

(算法3)二分查找

朴素二分查找 最直接的二分查找,有序,查找数组中的某个元素 这种方法是有局限性的:只可以查找升序的数组,且要查找的元素是一个 注意:mid(中点)的计算应该是:left(right-left)/2 (个数是偶数时…

接口测试06 -- pytest接口自动化封装Loggin实战

1. 接口关键字封装 1.1 基本概念 接口关键字封装是指:将接口测试过程中常用的操作、验证封装成可复用的关键字(或称为函数、方法),以提高测试代码的可维护性和可复用性。 1.2 常见的接口关键字封装方式 1. 发送请求:封装一个函数,接受参数如请求方法、URL、请求头、请求…

Sketch 99.1 for macOS

Sketch 99.1 for macOS 概述 这个程序是对矢量绘图的创新性和焕然一新的看法。它特意采用了极简主义的设计,基于一个大小无限、图层自由的绘图空间,没有调色板、面板、菜单、窗口和控件。 此外,它提供了强大的矢量绘图和文本工具,…

django通过指定用户手机号查询外键所关联的数据,倒序查询

django通过指定用户手机号查询外键所关联的数据 在Django中,可以通过使用filter方法和双下划线语法来查询外键所关联的数据。以下是一种常见的方法: from your_app.models import User, ForeignKeyModel# 假设User模型有一个名为phone的字段&#xff…

基于Spring Boot的美容院管理系统设计与实现,计算机毕业设计(带源码+论文)

源码获取地址: 码呢-一个专注于技术分享的博客平台一个专注于技术分享的博客平台,大家以共同学习,乐于分享,拥抱开源的价值观进行学习交流http://www.xmbiao.cn/resource-details/1757434902285987841

洛谷数组P1319压缩技术

做题思路: 这里表示输入的第一个数字N为N*N的方阵,后面的数字表示连续输入几个1或者0,定义result表示实际输出的数字0或1(result输出0或1,可以用绝对值abs我们初始化result为0,我们将它-1后再取绝对值就可以…

二、ClickHouse简介

ClickHouse简介 前言一、行式存储二、DBMS功能三、多样化引擎四、高吞吐写入能力五、数据分区与线程级并行六、场景七、特定版本 前言 ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库(DBMS),使用 C 语言编写,主要…

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easyrce解析

先看网页 代码审计: error_reporting(0); :关闭报错,代码的错误将不会显示 highlight_file(__FILE__); :将当前文件的源代码显示出来 eval($_GET[url]); :将url的值作为php代码执行 解题: 题目既然允许…

速盾:cdn集群防御空间dns服务器

在当今数字化时代,网络安全和性能成为了企业关注的焦点。速盾的CDN集群防御空间DNS服务器技术为网站提供了更高水平的安全性和性能优化。本文将深入探讨这一技术的关键特点和优势。 1. 集群防御: 速盾的CDN集群防御通过分布在全球的节点集群,…