Delphi语法基础(6)

2020-04-03 12:44

YearTemps = array [Jan..Dec] of MonthTemps;

上例的声明把索引的次序前后调换了一下,但仍允许变量之间整块赋值。例如:把一月份的温度值赋给二月份: var

ThisYear: YearTemps; begin ...

ThisYear[Feb] := ThisYear[Jan];

你也能定义下标从零开始的数组,不过这似乎不太合逻辑,因为你需要用下标2来访问数组第三项。然而,Windows一直沿用了从零开始的数组(因为它是基于C语言的),并且Delphi 控件库也在往这方向靠拢。

使用数组时,你总要用标准函数Low和 High来检测它的边界,Low和 High返回下标的下界和上界。强烈建议使用Low和 High操作数组,特别是在循环中,因为这样能使代码与数组范围无关,如果你改变数组下标的范围声明,Low和 High代码不会受影响;否则,如果代码中有一个数组下标循环体,那么当数组大小改变时你就不得不更新循环体的代码。Low和 High将使你的代码更易于维护、更稳定。

注意:顺便提一下,使用Low和 High不会增加系统运行额外开销。因为在编译时,他们已被转换成常数表达式,而不是实际函数调用。其他简单的系统函数也是这样。 Delphi主要以数组属性的形式使用数组。

注意:Delphi 4 的Object Pascal中增加了动态数组,所谓动态数组是在运行时动态分配内存改变数组大小。 记录类型

记录类型用于定义不同类型数据项的固定集合。记录中每个元素,或者说域,有它自己的类型。记录类型定义中列出了所有域,每个域对应一个域名,通过域名可以访问它。

下面简单列举了记录类型的定义、类型变量的声明以及这类变量的使用: type

Date = record Year: Integer; Month: Byte; Day: Byte; end;

21

var

BirthDay: Date; begin

BirthDay.Year := 1997; BirthDay.Month := 2; BirthDay.Day := 14;

类和对象可以看作是记录类型的扩展。Delphi 库趋向于用类替代记录类型,不过Windows API中定义了许多记录类型。

记录类型中允许包含variant 域,它表示多个域能公用同一内存区,而且域可以是不同类型(这相应于C语言中的联合union)。换句话说,你可以通过variant 域或说是一组域访问记录中同一个内存位置,但是各个值仍需区别对待。variant类型主要用来存贮相似但又不同的数据,进行与类型映射(typecasting)相似的类型转换(自从typecasting 引入Pascal,已很少用到这种方法了)。虽然Delphi在一些特殊情况下还在用variant 记录类型,但是现在已经被面向对象技术或其他现代技术代替了。

variant 记录类型的应用不符合类型安全原则,因此不提倡在编程中使用。

指针

指针是存放指定类型(或未定义类型)变量内存地址的变量,因此指针间接引用一个值。定义指针不需用特定的关键字,而用一个特殊字符,这个特殊字符是脱字符号(^),见下例: type

PointerToInt = ^Integer;

一旦你定义了指针变量,你就可以用@ 符号把另一个相同类型变量的地址赋给它。见下例: var

P: ^Integer; X: Integer; begin P := @X;

// change the value in two different ways X := 10; P^ := 20;

如果定义了一个指针P,那么P表示指针所指向的内存地址,而P^表示内存所存储的实际内容。因此,在上面的代码中, P^ 与X相等。

除了表示已分配内存的地址外,指针还能通过New 例程在堆中动态分配内存,不过当你不需要这个指针时,你也必须调用Dispose 例程释放你动态分配的内存。

22

var

P: ^Integer; begin

// initialization New (P); // operations P^ := 20;

ShowMessage (IntToStr (P^)); // termination Dispose (P); end;

如果指针没有值,你可以把nil 赋给它。这样,你可以通过检查指针是否为nil 判断指针当前是否引用一个值。这经常会用到,因为访问一个空指针的值会引起一个访问冲突错误,也就是大家知道的“一般保护错”(GPF)。见下例:

procedure TFormGPF.BtnGpfClick(Sender: TObject); var

P: ^Integer; begin P := nil;

ShowMessage (IntToStr (P^)); end;

通过运行例GPF,或者看图4.4,你可以看到上述这种结果。

图 4.4: 访问nil指针引起的系统错误

将上面程序加以修改,访问数据就安全了。现在将一个已存在的局部变量赋给指针,指针使用就安全了,虽然如此,还是加上了一个安全检查语句: procedure TFormGPF.BtnSafeClick(Sender: TObject);

23

var

P: ^Integer; X: Integer; begin P := @X; X := 100; if P <> nil then

ShowMessage (IntToStr (P^)); end;

Delphi 还定义了一个Pointer 数据类型,它表示无类型的指针(就象C语言中的void* )。如果你使用无类型指针,你应该用GetMem 例程,而不是New例程,因为GetMem 例程能用于内存分配大小不确定的情况。

实际上,Delphi 中必须使用指针的情况很少。虽然如此,若要进行高级编程和完全理解Delphi 对象模型,理解指针是很重要的,因为Delphi 对象模型在幕后使用了指针。

注意:虽然在Delphi中不常使用指针,但是经常会用一个极为相似的结构--引用(references)。每个对象实例实际上是一个隐含的指针,或说是对其实际数据的引用,利用引用,能象用其他数据类型一样使用对象变量。 文件类型

另一个Pascal特定的类型构造器是文件类型(file)。文件类型代表物理磁盘文件,无疑是Pascal语言的一个特殊类型。按下面的方式,你可以定义一个新的数据类型: type

IntFile = file of Integer;

然后,你就能打开一个与这个结构相应的物理文件、向文件中写入整数、或者从文件中读取当前的值。

Pascal 文件类型的使用很直观,而且Delphi 中也定义了一些控件用于文件保存和装载,以及对数据流和数据库的支持。

简单语句和复合语句

Pascal 简单语句中不包含任何别的语句,赋值语句和过程调用即是简单语句的例子。简单语句用分号隔开,如下所示: X := Y + Z; // assignment Randomize; // procedure call

24

用begin 和end 将简单语句括起来即组成复合语句,复合语句用法与普通的Pascal 语句相同,见下例: begin A := B; C := A * 2; end;

end之前的最后一条语句末尾分号不是必需的,你可以写成: begin A := B; C := A * 2 end;

这两种写法都是正确的。第一种多了一个无用(但也无害)的分号。分号实际上是一个空语句,也就是说,是一个没有代码的语句。有时,空语句可用在循环体或其他特殊情况中。 注意:虽然最后一条语句末尾的分号没有用,建议你也这样做。因为有时你可能需要在末尾添加语句,如果最后没有加分号,你就必须记着加上它,与其如此不如一开始就加上它。 赋值语句

在Pascal 语言中赋值语句用冒号-等号操作符“:=”,对使用其他语言的编程人员来说这是一个奇怪的符号。在其他语言中用作赋值符号的“=”在Pascal 中用作关系运算符,用于判断是否相等。

注意:赋值和相等判断使用不同的符号,使Pascal 编译器(象C编译器一样)能更快解译源代码,因为这样就不需要通过检查上下文来判断符号的意义,此外使用不同操作符也使代码更易读。 条件语句

条件语句通过条件检测,判断是否执行该条件语句中包含的语句。条件语句可有两种基本形式:if语句和case语句。

If语句

对if-then型语句,仅当条件满足时,语句才执行;对if-then-else型,if语句在两条语句中选择一条执行。条件用布尔表达式建立,这里通过一个简单的Delphi 例子来示范如何写条件语句。首先,创建一个应用程序,在form上面放两个复选框(check box)和四个按钮(button),

25


Delphi语法基础(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:清东陵 导游词 中英文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: