数组是可以通过索引来引用的同类型数据的列表。按照存储空间的获取方式,Delphi支持的数组类型有两种,即静态数组和动态数组。所谓静态数组就是在声明时就已经确定大小的数组类型,而动态数组是指其大小在声明时不能确定的数组,动态数组的大小在使用时确定。

声明静态数组的方式非常简单,只要指明数组长度和数据类型即可,下面就是声明了一个用来存放字符的数组:

var Hello: array[0..5] of char;

容易看出,数组的声明明显包含3个部分,关键词array表明这是一个数组变量,而[x..y]表明数组的索引是从x到y,而of char表明数组的成员是字符类型。按照类似的方法还可以声明其他类型的数组,下面就是这样的示例代码:

var ScoreList: array[1..25] of Integer;

var NameList: array[1..35] of String;

声明了数组后,可以通过索引引用数组的元素(成员)。而使用数组成员的方法与使用这种类型的普通变量类似,下面就是一段使用字符数组的示例代码:

var Hello: array[0..5] of char;

begin
 Hello[0] := ‘H’;
 Hello[1] := ‘e’;
 Hello[2] := ‘l’;
 Hello[3] := ‘l’;
 Hello[4] := ‘o’;
 Hello[5] := Chr(0);
 ShowMessage(Hello);
end;
这里声明了几个数组,它们都是只包含一个索引参数的数组,即一维数组。Delphi支持具有更多索引参数的数组,即多维数组。下面给出一段声明二维数组的示例代码:
var Hello: array[0..5][1..10] of char;
访问二维数组成员的方式与访问一维数组的方式相似,只要按照类似的方式指定两个索引就可以访问二维数组的成员,下面就是使用二维数组的示例代码:
var Hello: array[0..5] of array[0..10] of char;
begin
 Hello[0][0] := ‘H’;
 Hello[0][1] := ‘e’;
 Hello[0][2] := ‘l’;
 Hello[0][3] := ‘l’;
 Hello[0][4] := ‘o’;
 Hello[0][5] := Chr(0);
 ShowMessage(Hello[0]);
end;
按照类似的方法还可以声明具有更高维数的数组,这里不再给出实例。另外,Delphi还支持访问二维数组成员的另外一种方法,下面就是示例代码:
var Hello: array[0..5] of array[0..10] of char;
begin
 Hello[0,0] := ‘H’;
 Hello[0,1] := ‘e’;
 Hello[0,2] := ‘l’;
 Hello[0,3] := ‘l’;
 Hello[0,4] := ‘o’;
 Hello[0,5] := Chr(0);
 ShowMessage(Hello[0]);
end;
前面只是用了静态数组,Delphi还支持动态数组,动态数组在声明时不需指定数组的大小,而在使用时直接指定,下面就是定义动态数组的方法:
var ScoreList: array of Integer;
由于在声明时没有指定动态数组的大小,因此在使用前必须指定动态指定数组的大小,这是通过调用过程SetLength来实现的,下面就是指定动态数组大小的示例:
var
  I: Integer;
  StutCount: Integer;
  ScoreList: array of Integer;
begin
  StutCount := 50;
  SetLength(ScoreList, StutCount);
  // set the score list
  for I := 0 to StutCount - 1 do
  begin
    ScoreList[I] := Random(100);
  end;
  // print the score list
  for I := 0 to StutCount - 1 do
  begin
    ShowMessage('Stut Index: ' + IntToStr(I + 1) +
      #13#10 + 'Socre Value: ' + IntToStr(ScoreList[I]));
  end;
  // to finalize the score list
  SetLength(ScoreList, 0);
end;
这段代码首先使用StutCount变量来初始化数组的大小,然后为所有数组成员随机分配一个在0到100之间的整数,再利用对话框输出这些整数,最后再次使用SetLength将数组的长度设置为0,从而释放数组所占用的空间。另外,后面章节将说明,动态数组实际上就是一个指针。
4. 地址和指针
在学习Delphi程序设计时,地址的概念非常重要,它是理解指针变量的基础。所谓地址就是内存某个存储单元在内存中的位置,而这个位置是相对于内存中第一个存储单元而言的。如果将内存中第一个单元的地址记为0,第二个单元的地址记为1,则第1000个单元的地址就可以记为999。当然,这是一种最简单的记法,在执行应用程序时,实际的地址记法比较复杂,但它们的基本概念完全相同。另外,需要注意的是,只有在程序被加载到内存中开始执行时,程序中的所有变量才在内存中有了实际的对应存储单元,而此时的内存地址才具有实际意义,但编写程序的语言已经将这些底层的复杂问题都隐藏起来了,程序只要使用指针变量来表示指针就可以,不需要关心实际内存的地址。
指针就是用来表示内存地址的变量类型。实际上,绝大多数变量的地址是由程序语言自己来维护的,程序员不需要为这些变量的地址维护变量。指针是程序员为了管理某些与内存密切相关的变量而引入的一种变量类型,它专门用来记录内存中某段存储空间的起始地址的地址值,从而可以方便地找到这段存储空间,进而访问它的内容。
动态数组变量就是一种指针类型变量。数组在内存中是存放在一起的,即数组的多个成员是按照一定的顺序在内存中放在一起的,而动态数组变量就是一个指向这块内存起始地址的指针变量,通过调用这个指针变量,就可以访问数组的内容,前面已经给出了动态数组变量的用法。为了更加深入的说明这种情况,下面给出一个更为明显的例子:
var
  I: Integer;
  StutCount: Integer;
  ScoreList, MyScoreList: array of Integer;
begin
  StutCount := 50;
  SetLength(ScoreList, StutCount);
  // set the score list
  for I := 0 to StutCount - 1 do
  begin
    ScoreList[I] := Random(100);
  end;
  // print the score list
  MyScoreList := ScoreList;
  for I := 0 to StutCount - 1 do
  begin
    ShowMessage('Stut Index: ' + IntToStr(I + 1) +
      #13#10 + 'Socre Value: ' + IntToStr(ScoreList[I]) +
      #13#10 + 'My Socre Value: ' + IntToStr(MyScoreList[I])
      );
  end;
  // to finalize the score list
  SetLength(ScoreList, 0);
end;
正是因为动态数组变量只是一个用来保存内存地址的指针变量,因此上面以黑体显示的语句将使数组MyScoreList与ScoreList指向相同的内存地址,从而就变成实际意义上相同的数组,所以这段代码执行的效果将有力地说明动态数组变量就是指针这个事实。
  注意:但指针本身也是一个变量,它也必须存放在内存中,因此也有指向这个变量的内存的地址,而这个内存的地址是由程序语言自己维护的,不需要由程序员管理。实际上,前面已经说明,在程序运行时,所有变量都必须存放在内存中,都存在实际的地址,而这些地址并不需要程序员去管理的原因就是程序语言已经帮助程序员完成了管理变量地址的任务。

所有简单数据类型(整型、实型、布尔类型等)和大量复杂数据类型都存在相应的指针类型,如果程序需要使用这些变量的指针类型,则可以使用下面的示例代码:

var
  A: Integer;
  PA: PInteger;
begin
  A := 1;
  PA := @A;
  ShowMessage(IntToStr(PA^));
end;
只要将这段代码输入程序中,很容易就可以得到运行结果——即弹出对话框的内容是1。实际上,指针的用法还相当复杂,下面的代码也是正确的:
var
  A: Integer;
  PA: PInteger;
begin
  A := 1;
  PA := @A;
  PA^ := 2;
  ShowMessage(IntToStr(A));
end;
在程序中,根据实际需要,程序员还可以为自己定义的普通或复杂数据类型定义指针数据类型,下面就是定义指针数据类型的示例代码:
type
  PMyRec = ^TMyRec;
  TMyRec = record
    P1: Integer;
    P2: Integer;
    Name: String;
  end;
可以看出,这里定义了一个结构体类型,并定义它的指针类型PMyRec。在后续代码中,程序就可以使用这里定义的数据类型和指针数据类型,下面就是一段使用这种数据类型的示例代码:
var
  rec: TMyRec;
  mrec: PMyRec;
begin
  mrec := @rec;
  mrec^.P1 := 12;
  mrec^.P2 := 2029;
  mrec^.Name := 'mywork';
  ShowMessage(rec.Name + #13#10 + 'ID: ' +
IntToStr(rec.P1) + ', ' + IntToStr(rec.P2));
end;

说明:这里使用了一个结构体数据类型,并已经给出使用结构体数据类型的方法,这里不再详细说明。

原文:http://www.delphitop.com/html/jichu/1895.html

最新文章

  1. C语言 右左法则
  2. Android Support Annotations :安卓注解快速上手
  3. 防止忘记初始化NSMutableArray的方法
  4. Delphi用ADOquery主从表例子(转)
  5. REST Adapter实现SAP PI中的增强XML/JSON格式转换
  6. 数轴line
  7. 前端笔记之JavaScript面向对象(二)内置构造函数&相关方法|属性|运算符&继承&面向对象
  8. Thanks David's Share
  9. Metasploit Framework(3)Meterpreter
  10. 手动编译websocket-sharp项目使其支持.net core
  11. python 的__init__ 和__new__ 区别
  12. 【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)
  13. Vertica系列:Vertica和Hadoop的互操作性
  14. JAVA方法调用中的解析与分派
  15. php搜索附近人及显示男生女生分开
  16. 启用sa账号
  17. java基础基础总结----- System
  18. django的数据库操作
  19. 解决EditPlus在设置了UTF-8之后,编写的HTML页面仍出现汉字乱码问题
  20. 在eclipse pydev中使用PEP8来规范python代码

热门文章

  1. 25行 Python 代码实现人脸检测——OpenCV 技术教程
  2. Octave中调用hist出现broken pipe some output may be lost octave的解决(Mac)
  3. Django 新手图文教程 (转)
  4. Spring Boot实践——SpringMVC视图解析
  5. Keepalive VIP 故障
  6. win 10+ iis 10 部署.net core 1.1 web api
  7. 关于IP4上WIFI设置静态IP的一点经验
  8. 【冷门】 C# 小技巧之获取变量名称
  9. 必看的 jQuery性能优化的38个建议
  10. H5/