技术交流,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’

Delphi - 数组 详解的更多相关文章

  1. Delphi指针详解

    Delphi指针详解2007-12-04 06:08:57|  分类: DLL学习 阅读91 评论0   字号:大中小 订阅 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用 ...

  2. Delphi 关键字详解

    Delphi 关键字详解[整理于 "橙子" 的帖子] absolute //它使得你能够创建一个新变量, 并且该变量的起始地址与另一个变量相同. var   Str: ];   S ...

  3. 3.awk数组详解及企业实战案例

    awk数组详解及企业实战案例 3.打印数组: [root@nfs-server test]# awk 'BEGIN{array[1]="zhurui";array[2]=" ...

  4. JavaScript进阶(十)Array 数组详解

    JS array 数组详解 数组的声明方法 arrayObj = new Array(); 的数组 ,并且第一位是5 数组的运算(传地址) var t2=new Array(); t2[0]=1; t ...

  5. Java基础之 数组详解

    前言:Java内功心法之数组详解,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 数组概念 同一种类型数据的集合.其实数组就是一个容器. 数组 ...

  6. “全栈2019”Java第三十一章:二维数组和多维数组详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. “全栈2019”Java第三十章:数组详解(下篇)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. “全栈2019”Java第二十九章:数组详解(中篇)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  9. “全栈2019”Java第二十八章:数组详解(上篇)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. iOS 获取LaunchImage启动图

    iOS开发中,LaunchImage图片会根据手机机型的不同,自动匹配对应的图片,而我们如果想要拿到对应的图片,无法直接通过图片的名字获取该启动图,而需要通过以下方式 + (NSString *)ge ...

  2. Carthage:去中心化的Cocoa依赖管理器

    Cocoa的依赖管理器,我们已经有了CocoaPods,非常好用,那么为什么还要创建这样一个项目呢?本文翻译自Carthage的Github的README.md,带大家来了解一下这个工具有何不同之处. ...

  3. 【Mac系统 + Mysql】之安装Mysql数据库

    安装Mysql步骤: 一.下载 参考文章<mac 安装MySQL> 到Mysql官网下载.dmg格式的文件 先放弃了,看下面的简易安装. 二.使用homebrew安装MySQL(推荐) 如 ...

  4. Ueditor编辑器图片上传到万象优图

    最近想用typecho做一个个人博客站,typecho的文本编辑器不能上传图片,我就用Ueditor替换的了原来的文本编辑器,听说腾讯的万象优图每月有50G的免费空间和流量,我就自己改了下Uedito ...

  5. 从零开始学android -- Service

    废话不多说了,Service是四大组件之一,是一个后台处理长时间运行在主线程不需要依赖ui界面显示的应用组件,切记不能在service中做耗时操作,会阻塞主线程,要做也要在service中开个子线程做 ...

  6. 移动Web开发技巧汇总(转)

    META相关 1. 添加到主屏后的标题(IOS) <meta name="apple-mobile-web-app-title" content="标题" ...

  7. unity shader 编辑器扩展类 ShaderGUI

    这应该unity5才出的新功能了,今天看文档时刚巧看到了,就来尝试了一下. 效果如图: shader 的编辑器扩展分为2种方法: 是通过UnityEditor下的ShaderGUI类来实现的,形式比较 ...

  8. python入门课程 第3章 Python变量和数据类型

    第3章 Python变量和数据类型3-1 Python中数据类型计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形 ...

  9. 从xhr说起

    原生xhr对象存在较多的兼容性,IE6及之前版本使用ActiveXObject对象来创建,IE7以后使用兼容版本的MSXML2.XMLHttp.MSXML2.XMLHttp3.0.MSXML2.XML ...

  10. iostat命令简单使用

    1.iostat使用范围 iostat命令可以生成3种类型的报告: (1)CPU使用情况的报告 (2)设备使用情况的报告 (3)网络文件系统(NFS)使用情况的报告 2.每种报告的格式说明 关于CPU ...