c语言 文件 子界型,第四章 用户自定义数据类型

var

UppLetter: UpperCase;

begin

UppLetter := 'F';枚举类型

枚举类型又是一种自定义有序类型。在枚举类型中,你列出所有该类

型可能取的值,而不是指定现有类型的范围。换句话说,枚举类型是

个可取值的序列。见下例:type Colors = (Red, Yellow, Green, Cyan, Blue, Violet); Suit = (Club, Diamond, Heart, Spade);

序列中每个值都对应一个序号,序号从0开始计数。使用Ord 函数,即可得到一个枚举类型

值的序号。例如,Ord (Diamond) 返回值1。

集合类型

集合类型表示一组值,该组值由集合所依据的有序类型定义。定义集合的常用有序类型不多

,一般为枚举类型或子界类型。如果子界类型取值为1..3,那么基于它的集合类型值可以

是1、或2、或3、或1和2、或1和3、或2和3、或取所有3个数、或一个数也没有。

一个变量通常包含该类型对应的一个值,而集合类型可以不包含值、包含一个值、两个值、

三个值,或更多,它甚至可以包含定义范围内所有的值。下面定义一个集合:

type Letters = set of Uppercase;

现在我可以用上面类型来定义变量,并把原始类型的值赋给变量。为了在集合中表示一组值

,需要用逗号将值隔开,最后用方括号结尾。下例显示了多值、单值和空值的变量赋值:

var

Letters1, Letters2, Letters3: Letters;

begin

Letters1 := ['A', 'B', 'C'];

Letters2 := ['K'];

Letters3 := [];

数组类型

数组类型定义了一组指定类型的元素序列,在方括号中填入下标值就可访问数组中的元素。

定义数组时,方括号也用来指定可能的下标值。例如,下面的代码中定义了一个有24个整数

的数组:

type DayTemperatures = array [1..24] of Integer;

在数组定义时,你需要在方括号中填入一个子界类型的值,或者用两个有序类型的常量定义

一个新的子界类型,子界类型指定了数组的有效索引。由于子界类型指定了数组下标值的

上界和下界,那么下标就不必象C、C++、JAVA和其他语言那样必须从零开始。

由于数组下标基于子界类型,因此Delphi 能够对它们进行范围检查。不合法的常量子界类型

将导致一个编译时间错误;如果选上编译器范围检查选项,那么超出范围的下标值将导致一个

运行时间错误。

使用上述数组定义方法,定义一个DayTemperatures类型的变量如下:

type

DayTemperatures = array [1..24] of Integer;

var

DayTemp1: DayTemperatures;

procedure AssignTemp;

begin

DayTemp1 [1] := 54;

DayTemp1 [2] := 52;

...

DayTemp1 [24] := 66;

DayTemp1 [25] := 67; // compile-time error

数组可以是多维的,如下例:

type MonthTemps = array [1..24, 1..31] of Integer; YearTemps = array [1..24, 1..31, Jan..Dec] of Integer;

这两个数组建立在相同的核心类型上,因此你可用前面定义的数据类型声明它们,如下面代

码所示:

type

MonthTemps = array [1..31] of DayTemperatures;

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主要以数组属性的形式使用数组。我们已经在 TimeNow 例子中看到过数组属性,

也就是ListBox控件的Items 属性。下一章讨论Delphi循环时,我将向你介绍更多有关数组

属性的例子。 记录类型

记录类型用于定义不同类型数据项的固定集合。记录中每个元素,或者说域,有它自己的

类型。记录类型定义中列出了所有域,每个域对应一个域名,通过域名可以访问它。

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

type Date = record Year: Integer; Month: Byte; Day: Byte; end; 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 记录类型的应用不符合类型安全原则,因此不提倡在编程中使用,初学者更是如此。

实际上,专家级的编程人员确实需要用到variant 记录类型,Delphi 库的核心部分就用到

了这一类型。不管怎样,除非你是个Delphi 专家,否则你应避免使用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例程释放你动态分配的内存。 var

P: ^Integer;

begin

// initialization

New (P);

// operations

P^ := 20;

ShowMessage (IntToStr (P^));

// termination

Dispose (P);

end;

文件类型

另一个Pascal特定的类型构造器是文件类型(file)。文件类型代表物理磁盘文件,无疑

是Pascal语言的一个特殊类型。按下面的方式,你可以定义一个新的数据类型:type IntFile = file of Integer;

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

读取当前的值。

Pascal 文件类型的使用很直观,而且Delphi 中也定义了一些控件用于文件保存和装载,

以及对数据流和数据库的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值