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

5.1.4 动态数组

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

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

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

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

var
  Array1: 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 示例中,我使用自适应循环从动态数组中填充和提取信息。这是类型和变量定义:

type
  TIntegersArray = array of Integer;
  
var
  IntArray1: TIntegersArray;

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

var
  I: Integer;
  
begin
  SetLength(IntArray1, 20);
  for I := Low(IntArray1) to High(IntArray1) do
    IntArray1[I] := I;
end;

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

var
  I: Integer;
  Total: Integer;
  
begin
  Total := 0;
  for I := Low(IntArray1) to High(IntArray1) do
  begin
    Inc(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函数,该函数在新的数据结构中使用单独的内存区域复制数组数据
  • 使用赋值运算符,它实际上创建了一个别名,即一个新变量,引用相同的内存中的相同数组

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

var
  IntArray2: 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中引入了对常量数组的赋值和连接的支持。以下是一个示例,演示了这些操作:

var
  DI: array of Integer;
  I: Integer;

begin
  DI := [1, 2, 3];       // 初始化
  DI := DI + DI;         // 连接
  DI := DI + [4, 5];      // 混合连接

  for I in DI do
  begin
    Show(I.ToString);
  end;
end;

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

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

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

var
  DI: array of Integer;
  I: Integer;

begin
  DI := [1, 2, 3, 4, 5, 6];

  Insert([8, 9], DI, 4);
  Delete(DI, 2, 1);  // 删除第三个项目(zero-based index)
end;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ucosIII下创建任务读取DS18B20采集到的温度数据

学习链接:ucosIII下创建任务读取并输出DHT11采集到的温湿度数据 相关代码及事项: 首先,需要添加下面两个文件, 其次,main.c 中如下的代码: #include "led.h" #include "delay.h" #…

第10集《佛说四十二章经》

请大家打开讲议第十一面,第十九章、假真并观。 前面一章念等本空,说明大乘佛法的修学,身口意应安住在非空非有的中道实相。本章对中道实相的修学,再做明确的说明。修中道实相观要有空观与假观的观照,从空观中远离有相…

VueCLI核心知识综合案例TodoList

目录 1 拿到一个功能模块首先需要拆分组件: 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来…

​StableSwarmUI#超越文本的prompt

今天看到一个新的webui方案,是Stability-AI开源的: StableSwarmUI 是一个模块化的稳定扩散web用户界面,着重于使强大的工具易于访问、高性能和可扩展性。 由于项目还在开发中,我们可以先了解下,翻看了它的特点&#xf…

幻兽帕鲁游戏联机的时候,显示“网络连接超时”怎么解决?

如果你在游戏联机的时候,显示“网络连接超时”,可以检查下: 1、前提是你已经按照教程部署成功 2、检查防火墙有没有忘记设置,协议是UDP(只有TCP不行,一定要有UDP),端口是否填了8211&…

K210开发环境搭建(VS Code)

一、新建一个文件夹,就叫K210 二、再K210文件夹里面再新建一个文件夹,就叫CMake 三、找到官方提供的资料包里的cmake安装包, 或者直接去cmake官方下载网址进行下载 CMake官方下载网址:https://cmake.org/download/ 四、双击安装…

每日一题 (不用加减乘除做加法,找到数组中消失的数字)

不用加减乘除做加法_牛客题霸_牛客网 (nowcoder.com) 可以使用位运算符实现两个整数的加法: 在二进制加法中,我们通常使用“逐位相加”的方法来模拟常规加法的过程。当两个数字进行加法运算时,从最低位(通常是右侧)开…

开源≠不赚钱,开源软件盈利的7大模式。

开源不是目的,目的是圈用户,留住用户,盈利自然不成问题。 开源系统可以通过多种方式赚钱,以下是其中几种常见的方式: 提供付费支持: 开源系统可以提供付费的技术支持服务,包括安装、配置、维…

PyTorch深度学习快速入门教程 - 【小土堆学习笔记】

小土堆Pytorch视频教程链接 声明: 博主本人技术力不高,这篇博客可能会因为个人水平问题出现一些错误,但作为小白,还是希望能写下一些碰到的坑,尽力帮到其他小白 1 环境配置 1.1 pycharm pycharm建议使用2020的&…

ArcgisForJS基础

文章目录 0.引言1.第一个ArcgisForJS应用程序1.1.安装部署ArcgisForJS1.2.实现ArcgisForJS应用程序 2.开发与调试工具2.1.集成开发环境2.2.调试工具2.3.Firebug 0.引言 ArcGIS API for JavaScript是一款由Esri公司开发的用于创建WebGIS应用的JavaScript库。它允许开发者通过调…

【王道数据结构】【chapter5树与二叉树】【P158t9】

假设二叉树采用二叉链存储结构存储&#xff0c;设计一个算法&#xff0c;求先序遍历序列中第k个结点的值 #include <iostream> #include <stack> typedef struct treenode{char data;struct treenode *left;struct treenode *right; }treenode,*ptreenode;ptreenod…

支付交易——清结算

摘要 老王有个账本&#xff0c;店里进了哪些货、进的谁家货、花了多少钱&#xff0c;老王都会—一记下来;卖了哪些货、卖给了谁、卖了多少钱&#xff0c;也都会记下来。为什么要有个账本&#xff0c;看看老王是怎么进货和卖货的就知道了。老王店里虽然商品种类很多&#xff0c…

【数据结构】图

文章目录 图1.图的两种存储结构2.图的两种遍历方式3.最小生成树的两种算法&#xff08;无向连通图一定有最小生成树&#xff09;4.单源最短路径的两种算法5.多源最短路径 图 1.图的两种存储结构 1. 图这种数据结构相信大家都不陌生&#xff0c;实际上图就是另一种多叉树&…

刘谦竟然不是第一个吃螃蟹的!——历年春晚数学魔术精选

早点关注我&#xff0c;精彩不错过&#xff01; 在今年2024的央视春晚&#xff0c;刘谦用一个手法数学魔术的流程&#xff0c;配合上小尼的完美衬托&#xff0c;时隔5年&#xff0c;再一次为全国观众见证奇迹。 如此江湖地位的加持&#xff0c;使得他表演什么甚至失误都已经不再…

MySQL 基础知识(五)之数据增删改

目录 1 插入数据 2 删除数据 3 更改数据 创建 goods 表 drop table if exists goods; create table goods ( id int(10) primary key auto_increment, name varchar(14) unique, stockdate date )charsetutf8; 1 插入数据 当要插入的数据为日期/时间类型时&#xff0c;如果…

Python数学建模之回归分析

1.基本概念及应用场景 回归分析是一种预测性的建模技术&#xff0c;数学建模中常用回归分析技术寻找存在相关关系的变量间的数学表达式&#xff0c;并进行统计推断。例如&#xff0c;司机的鲁莽驾驶与交通事故的数量之间的关系就可以用回归分析研究。回归分析根据变量的…

2048游戏C++板来啦!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习如何用C编写一个2048小游戏。 文章目录 1.2048的规则 2.步骤实现 2.1: 初始化游戏界面 2.1.1知识点 2.1.2: 创建游戏界面 2.2: 随机…

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1, 因为在此系统上禁止运行脚本

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1&#xff0c;因为在此系统上禁止运行脚本 今天在VSCode中运行ng serve --port 8081运行基于Angular的项目时&#xff0c;报错了&#xff0c;错误如下图所示&#xff1a; 解决方法&#xff1a; 按照下图的5步即…

【AI视野·今日NLP 自然语言处理论文速览 第七十八期】Wed, 17 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 17 Jan 2024 (showing first 100 of 163 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deductive Closure Training of Language Models for Coherence, Accur…

一探Lepton Search究竟

2024年1月25日&#xff0c;阿里巴巴原技术副总裁在 Twitter 上称用不到 500 行 Python 代码实现了 AI 对话搜索引擎&#xff0c;并在27日附上了开源地址&#xff1a;https://github.com/leptonai/search_with_lepton&#xff0c;截止春节期间已经5.8K的Star。 Twitter截图 Comm…
最新文章