技术交流,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. Google Code Jam 2014 资格赛:Problem D. Deceitful War

    This problem is the hardest problem to understand in this round. If you are new to Code Jam, you sho ...

  2. 对无向图的深度优先搜索(DFS)

    [0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 如何对无向图进行深度优先搜索 的idea 并用源代码加以实现: 0.2) 本文还引入了 背向边(定义见下文 ...

  3. Ubuntu下VirtualBox虚拟机与主机机互相ping通的简单配置心得

    virtualbox 是个非常优秀的软件,通常与主机之间有3种方式,Bridged方式,NAT方式,host-only方式,安装的默认方式是NAT,可是这样的方式在virtualbox虚拟机下有个缺点 ...

  4. 安装Hadoop 1.1.2 (一 安装JDK)

    1 下载jdk1.7 xxx .rpm 2 以Root权限登陆 3 修改文件权限  chmod +x jdk-7u25-linux-x64.rpm 4 安装 JDK  rpm -ivh jdk-7u2 ...

  5. 【iOS开发-80】Quartz2D绘图简介:直线/圆形/椭圆/方形以及上下文栈管理CGContextSaveGState/CGContextRestoreGState

    本文转载至 http://blog.csdn.net/weisubao/article/details/41282457 - (void)drawRect:(CGRect)rect { //获得当前上 ...

  6. 【基础版限时免费】致敬WebForms,ASP.NET Core也能这么玩!

    ASP.NET WebForms ASP.NET WebForms 随着微软 2000 年的 .Net Framework 一起发布,至今也将近 20 年的时间.相信很多人和我一样,对 WebForm ...

  7. Jaxb2 实现JavaBean与xml互转

    一.简介 JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实 ...

  8. What happens when we continue stacking deeper layers on a “plain” convolutional neural network?

    http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture9.pdf The deeper model performs worse, but ...

  9. jQuery对象转成DOM对象:

    jQuery对象转成DOM对象: 两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); (1)jQuery对象是一个数据对象,可以通过[index]的方法,来得 ...

  10. VIM复制粘贴 的快捷键是什么

    yy复制游标所在行整行.或大写一个Y. 2yy或y2y复制两行. ㄟ ,请举一反三好不好! :-) y^复制至行首,或y0.不含游标所在处字元. y$复制至行尾.含游标所在处字元. yw复制一个wor ...