Delphi - 数组 详解
技术交流,DH讲解.
首先我们要知道什么是数组?数组是一堆相同特性数据的一个集合,也就是每个元素的类型必须是一样的,当然在其他一些弱语法的语言里面,数组的元素可以千奇百怪.
例子:
1
2
3
4
5
6
|
Var
A: Array [ 0..2 ] Of Integer ;
Begin
A[ 0 ] := 1 ;
A[ 1 ] := 1.0 ; //这里是错的,因为每个元素都必须是Integer类型
End ;
|
Delphi中数组分类:
1 定长和不定长.
定长数组:也就是长度在声明的时候就确定了,后面是不能改变的,而在定长数组中,起始序号不必从0开始,可以自己定.例如:
1
2
3
4
5
6
|
Var
A: Array [ 2..3 ] Of Integer ;
Begin
A[ 2 ] := 1 ;
SetLength(A, 3 ); //这里会出错,定长数组不能再分配
End ;
|
从上面我们可以看到起始序号是2,但是步长是1,是不能改变的.为什么我们看到很多数组的起始序号都是0呢?习惯而已.大家都习惯在厕所里面去嘘嘘,而你一个人习惯在广场上面嘘嘘,那么大家都会说你不文明了.但是如果大家一开始都是在广场上面嘘嘘的话,不说了太恶心了.
来看一个特殊的用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
type
THuangJacky = (hjA,hjB,hjC);
const
//用法1
B: array [ 0..2 ] of string = ( 'A' , 'B' , 'C' );
//用法2
C: array [THuangJacky] of string = ( 'A' , 'B' , 'C' );
Var
H:THuangJacky;
S: string ;
Begin
S:=B[Ord(H)];
S:=C[H];
//B[H] 和 C[1]都会出错
End ;
|
用法1 和用法2你觉得那种用着爽一些?
从上面例子可以看出来只要是序数类型都可以当数组的序号.但是我们用的时候序号就必须是声明的那种序数类型,所以上面代码注释中才会写出2种错误的情况.
不定长数组:动态数组,也就是声明的时候没有说长度是多少,在使用前必须声明,长度可以再分配.序号必须从0开始.看个简单的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Var
A: Array Of Integer ;
Begin
SetLength( A, 3 ) ; //数组一共有3个元素
A[ 0 ] := 1 ;
A[ 1 ] := 2 ;
A[ 2 ] := 3 ;
//A[3]没有它,有它的话,你数一下几个了?不会数数,那我推荐你去街道口小学看一下
SetLength( A, 4 ) ; //如果变长长度,直接增加后面的元素
A[ 3 ] := 4 ; //现在有它了.
SetLength( A, 3 ) ; //如果长度变短,超出部分会被去掉
// A[3]又没有它了
End ;
|
有时候大家这样要先设定长度,然后再赋值,是不是很麻烦?没有一气呵成的感觉.好吧,再说一招:
1
2
3
4
5
6
7
8
9
|
Type
TA = Array Of Integer ;
Var
A: TA ;
Begin
A := TA . Create( 1 , 2 , 3 ) ;
//此招请勿在D7上面使用
//这样A[0]:=1,A[1]:=2,A[2]:=3
End ;
|
2 一维和多维.
前面所有例子,我们都只是说了一维数组,要是现在我们想弄一个矩阵(多维数组)怎么办?
1
2
3
4
5
6
7
|
Var
A: Array [ 0 .. 2 , 0 .. 2 ] Of Integer ;
B: Array [ 0 .. 2 ] Of Array [ 0 .. 2 ] Of Integer ;
Begin
A[ 0 , 0 ]:= 1 ;
A[ 0 ][ 0 ]:= 1 ;
End ;
|
两种方法都可以的.
1
2
3
4
5
6
7
8
9
10
|
Var
B: Array Of Array Of Integer ;
Begin
SetLength(B, 3 , 3 ); // 3*3矩阵
// 如果要实现齿状数组,必须这么做
SetLength(B, 3 );
SetLength(B[ 0 ], 1 ); // *
SetLength(B[ 1 ], 2 ); // **
SetLength(B[ 2 ], 3 ); // ***
End ;
|
接下来我们说说几个关于数组中常用的函数:
第一个 复制数组
1
2
3
4
5
6
7
8
9
|
Var
A, B: Array [ 0 .. 1 ] Of Integer ;
Begin
A[ 0 ]:= 1 ;
A[ 1 ]:= 2 ;
B:= A;
B[ 0 ]:= 2 ;
ShowMessageFmt( 'A0:%D,B0:%D' , [A[ 0 ], B[ 0 ]]); // A0:1,B0:2
End ;
|
这个效果就是我们想要的,貌似没有什么好说的.如果是动态数组呢?
1
2
3
4
5
6
7
8
9
10
11
|
Var
A, B: Array Of Integer ;
Begin
SetLength(A, 2 );
SetLength(B, 2 );
A[ 0 ]:= 1 ;
A[ 1 ]:= 2 ;
B:= A;
B[ 0 ]:= 2 ;
ShowMessageFmt( 'A0:%D,B0:%D' , [A[ 0 ], B[ 0 ]]); // A0:2,B0:2
End ;
|
现在怎么办?A和B被关联到了一个地址了,其实现在我们可以使用Copy函数,对就是复制字符串的那个函数:
1
2
3
4
5
6
7
8
9
10
11
12
|
Var
A, B: Array Of Integer ;
Begin
SetLength(A, 2 );
SetLength(B, 2 );
A[ 0 ]:= 1 ;
A[ 1 ]:= 2 ;
B:= Copy(A); // 整个数组都复制过去
B:= Copy(A, 0 , 2 ); // 选择性复制
B[ 0 ]:= 2 ;
ShowMessageFmt( 'A0:%D,B0:%D' , [A[ 0 ], B[ 0 ]]); // A0:1,B0:2
End ;
|
第二个 序号相关
函数Low()和High()值得信赖,不过我们需要注意的是,它们返回的类型是我们数组的序号的那个类型,并不都是Integer,如前面例子中的THuangJacky.
1
2
3
4
5
6
7
8
9
10
11
12
|
var
A : array of array of string ;
I, J : Integer ;
begin
SetLength(A, 10 );
for I := Low(A) to High(A) do
begin
SetLength(A[I], I);
for J := Low(A[I]) to High(A[I]) do
A[I,J] := IntToStr(I) + ',' + IntToStr(J) + ' ' ;
end ;
end ;
|
第三个 数组长度
Length()函数返回的就一定是是Integer了,因为个数不是整数难道还有半个么?
1
2
3
4
5
6
|
Var
A: Array Of Integer ;
Begin
SetLength(A, 2 );
Length(A); // 返回2
End ;
|
1
|
|
最后说个问题我就不说了:
从上面那个复制的例子我们可以看出来什么东西?
定长数组变量就是一个变量,所以可以直接用:=来赋值,而动态数组变量就是一个指针,如果用了:=来赋值2个变量就关联在一起了.
1
2
3
4
5
6
7
8
|
Var
A: Array [ 0 .. 2 ] Of Integer ;
B: Array Of Integer ;
Begin
ShowMessageFmt( 'A:%8x,A[0]:%8p' , [ Integer (@A), @A[ 0 ]]); // 一样,从地址来看这个数组空间在栈上面
SetLength(B, 3 );
ShowMessageFmt( 'B:%8p,B[0]:%8p' , [B, @B[ 0 ]]); // 一样,这个数据空间在堆上面
End ;
|
我们看到A要取地址才和A[0]取地址一样,那么也就是说A就是A[0].
而B直接就和B[0]取地址一样了,也就是说B就是B[0]的地址.
数组在内存中的分布:连续分布的,间隔就是每个元素的大小.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Var
A: Array [ 0 .. 2 ] Of Integer ;
B: Array Of Integer ;
Begin
A[ 1 ]:= 123 ;
// 从A也就是A[0]的地址上面 往下走4个直接 就是A[1]
ShowMessageFmt( 'A[1]:%D,直接取值:%D' , [A[ 1 ], PInteger( Integer (@A)+ 4 )^]);
// 一样,都是123
SetLength(B, 3 );
B[ 2 ]:= 88 ;
// 从B往下走8个字节就是B[2]
ShowMessageFmt( 'B[2]:%D,直接取值:%D' , [B[ 2 ], PInteger( Integer (B)+ 8 )^]); // 一样,88
End ;
|
但是动态数组的结构和字符的结构就很像了:
偏移 | -8 | -4 | 0~Length*元素大小-1 |
内容 | 32位引用次数 | 元素个数 | 实际内容 |
SetLength: 设定数组长度
SetLength(MyArray, 5) // 设定MyArray数组长度为5
High: 传回注脚的最大值,如果参数为数组类型的话,则是返回数组索引的最大值
High(MyArray) // 返回值为5
Copy: 字符串截取函数
Copy('substring', 4, 3) // 返回值为‘str’
转载于:https://www.cnblogs.com/chenmfly/p/4858913.html
Delphi - 数组 详解相关推荐
- Delphi 关键字详解[整理于 橙子 的帖子]
Delphi 关键字详解[整理于 "橙子" 的帖子] absolute //它使得你能够创建一个新变量, 并且该变量的起始地址与另一个变量相同. var Str: string[3 ...
- 【数据结构】树状数组详解(Leetcode.315)
前言 最近做题时遇到一个关于树状数组的题力扣https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/但是CSDN上仅有 ...
- JavaScript数据结构与算法——数组详解(下)
1.二维与多维数组 JavaScript只支持一维数组,但是通过在数组里保存数组元素的方式,可以轻松创建多维数组. 1.1 创建二维数组 二维数组类似一种由行和列构成的数组表格,在JavaScript ...
- JavaScript数组结构与算法——数组详解(中)
迭代器方法 在上篇中,我们探讨了很多数组方法,接下来总结一下最后一组方法--迭代器方法.这些方法对数组的每个元素应用一个函数,可以返回一个值.一组值.或者一个新数组. 1.不生成新数组的迭代器方法 以 ...
- Java中大数据数组,Java基础学习笔记之数组详解
摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...
- Scala 中的 Array 数组 详解
Scala 中的 Array 数组 详解 1. 一维数组的声明与遍历 2. 二维数组的声明与遍历 3. 可变长度数组 ArrayBuffer 4.数组其余方法详解 Scala 语言中提供的数组是用来存 ...
- KMP算法之next数组详解
KMP算法之next数组详解 KMP算法实现原理 KMP算法是一种非常高效的字符串匹配算法,下面我们来讲解一下KMP算如何高效的实现字符串匹配.我们假设如下主串和模式串: int i;//i表示主串的 ...
- php遍历关联数组详解,php遍历关联数组
php 动态关联数组,PHP 反射API,php遍历关联数组,php关联数组的输出 PHP数组详解_计算机软件及应用_IT/计算机_专业资料.PHP数组语法及其应用详细讲解,深入的探讨了数组的用法,以 ...
- C语言0长度数组(可变数组/柔性数组)详解
CSDN GitHub C语言0长度数组(可变数组/柔性数组)详解 AderXCoding/language/c/zero_length_array 本作品采用知识共享署名-非商业性使用-相同方式共享 ...
最新文章
- 联邦学习的隐忧:来自梯度的深度泄露
- python装饰器实例-基于Python 装饰器装饰类中的方法实例
- VTK:可视化算法之PlateVibration
- html代码中本地路径里斜杠 / 和反斜杠 \ 的区别
- python将非0数视为false_python 面试题
- 动手学CV-目标检测入门教程:基本概念
- 如何从零开始设计一颗芯片?
- SqlMap自动化SQL注入测试工具简绍
- angular 居中_Angular Material design设计
- 第四步_安装gcc交叉编译工具
- A*算法 带cocos2d-x例子 a*寻路算法
- 【RGB检测】基于matlab GUI图像RGB检测【含Matlab源码 088期】
- 伪静态 全站php 跳到html,IIS下万能301跳转方法:URL伪静态重写+PHP301
- 计算机文档调换顺序,word文档页面顺序调换
- 【时间同步】IEEE-1588总结
- 铁路计算机工程师论文,工程技术类有关论文格式模板,关于铁路工程师职文2016年相关论文范本...
- linux之ab测试
- nodejs 写入html,html2markdownnodejs也能写爬虫?记一次blog迁移至Ghost
- 题解 [校内测试]图森破
- uniapp中回退到上一页面并触发函数的方法
热门文章
- IDEA多行缩进快捷键
- r240显卡 linux,NV发布260.19.36正式版Linux驱动 270系列将至
- leetcode每日一题系列——787. K 站中转内最便宜的航班
- linux桌面版排行2019_2019 年适合新手的 Linux 发行版 top 5
- 消息队列面试经典十连问
- MySQL 实战 定时备份数据库
- Spring Cloud Alibaba 高级特性 基于 Sleuth+Zipkin 实施链路跟踪体系
- Spring Security 源码分析:Spring Security 授权过程
- CSS display 属性
- k8s多master建议用几个_Kubernetes 教程之跟着官方文档从零搭建 K8S