上一题下一题
跳转到
 
 
  世界如此多姿,发展如此迅速,窥一斑未必还能知全豹。但正如万花筒一样,每一个管窥都色彩斑斓。  
 
 
  知识通道 | 学习首页 | 教师首页 | PK首页 | 知识创造首页 | 企业首页 | 登录
 
本文对应知识领域
DELPHI语法编程基础(4)
作者:未知 申领版权
2010年12月12日 共有 1480 次访问 【添加到收藏夹】 【我要附加题目
受欢迎度:

    命名及不命名的类型 
    为了后续使用或直接用于变量,需要给自定义类型命名。如果自定义一个命名的类型,你必须将代码放在特定的type区,如下所示:
    type
    // subrange definition
    Uppercase = 'A'..'Z';
    
    // array definition
    Temperatures = array [1..24] of Integer;
    
    // record definition
    Date = record
    Month: Byte;
    Day: Byte;
    Year: Integer;
    end;
    
    // enumerated type definition
    Colors = (Red, Yellow, Green, Cyan, Blue, Violet);
    
    // set definition
    Letters = set of Char;
    你也可使用类型定义构造器直接定义一个变量,此时无需显式命名,如下面的代码:
    var
    DecemberTemperature: array [1..31] of Byte;
    ColorCode: array [Red..Violet] of Word;
    Palette: set of Colors;
    注意:一般来说,你应该避免使用上述不命名类型,因为你不能把它们作为参数传给例程,也不能用于声名同一类型的其他变量。实际上,Pascal的类型兼容规则是基于类型名的,而不是基于实际的类型定义。两个类型相同的变量仍有可能是不兼容的,除非他们的类型有完全相同的名字。对于不命名类型,需要编译器给它分配一个内部名字,因此对于数据结构复杂的变量,要习惯于定义命名数据类型,你一定不会为此白费工夫的。
    子界类型 
    子界类型定义了某种类型的取值范围(因此定名subrange)。你可定义整数类型的子界类型,如取值从1到10或从100到1000,或者定义字符类型的子界类型,如下所示: 
    type
    Ten = 1..10;
    OverHundred = 100..1000;
    Uppercase = 'A'..'Z';
    定义子界类型时,你不需要指定基类的名字,而只需提供该类型的两个常数。所用基类必须是有序类型,定义结果将是另一种有序类型。
    如定义一个子界变量,那么赋给该变量的值必须是子界定义范围内的值。下面代码是正确的:
    var
    UppLetter: UpperCase;
    begin
    UppLetter := 'F';
    以下代码则是不正确的: 
    var
    UppLetter: UpperCase;
    begin
    UppLetter := 'e'; // compile-time error
    以上代码将导致一个编译错误:“Constant expression violates subrange bounds”。
    如果代之以下面代码:
    var
    UppLetter: Uppercase;
    Letter: Char;
    begin
    Letter :='e';
    UppLetter := Letter;
    Delphi 编译会通过,但在运行时,如果你开启了范围检查编译选项(在工程选项对话框的编译器页设置),你将得到 Range check error (范围检测错误)信息。
    注意:建议你在开发程序时开启上述编译选项,以使程序更健壮并易于调试。这样即使遇上错误,你也会得到一个明确的信息而不是难以琢磨的行为。最终完成程序时你可以去掉这个选项,使程序运行得快一些,不过影响很小。因此我建议你开启所有运行时的检测选项,如溢出检查和堆栈检查,甚至提交程序时仍然保留它们。
    枚举类型 
    枚举类型又是一种自定义有序类型。在枚举类型中,你列出所有该类型可能取的值,而不是指定现有类型的范围。换句话说,枚举类型是个可取值的序列。见下例:
    type
    Colors = (Red, Yellow, Green, Cyan, Blue, Violet);
    Suit = (Club, Diamond, Heart, Spade);
    序列中每个值都对应一个序号,序号从0开始计数。使用Ord 函数,即可得到一个枚举类型值的序号。例如,Ord (Diamond) 返回值1。
    注意:枚举类型有多种内部表示法。缺省时,Delphi 用8位表示法;如果有多于256个不同的值,则用16位表示法。还有一种32位表示法,需要与C、C 库兼容时会用到。使用$Z 编译指令可改变缺省设置,请求更多位的表示法。
    集合类型 
    集合类型表示一组值,该组值由集合所依据的有序类型定义。定义集合的常用有序类型不多,一般为枚举类型或子界类型。如果子界类型取值为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 := [];
    在Delphi中,集合一般用于表示有多种选择的标记。例如下面两行代码(摘自Delphi库)声明了一个枚举类型,其中列出了窗口条上可选的图标,并声明了相应的集合类型:
    type
    TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);
    TBorderIcons = set of TBorderIcon;
    实际上,给定的窗口中可以没有图标,也可以有一个或多个图标。用Object Inspector设置时(见图4.3),双击属性名,或单击属性左边的加号,自行选择,从而添加或删除集合中的值。
    图 4.3: Object Inspector中的集合类型属性 
    
    另一个基于集合类型的属性是字体。字体类型值可以是粗体、斜体、带下画线、带删除线等,一种字型可以既是斜体又是粗体,也可以没有属性,或者带有全部的属性。因此用集合类型来表示它。你可以象下面代码那样,在程序中给集合赋值:
    Font.Style := []; // no style
    Font.Style := [fsBold]; // bold style only
    Font.Style := [fsBold, fsItalic]; // two styles
    你也能对一个集合进行许多不同方式的操作,包括把两个相同类型的集合变量相加(或更准确地说,计算两个集合变量的并集):
    Font.Style := OldStyle   [fsUnderline]; // two sets
    数组类型 
    数组类型定义了一组指定类型的元素序列,在方括号中填入下标值就可访问数组中的元素。定义数组时,方括号也用来指定可能的下标值。例如,下面的代码中定义了一个有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主要以数组属性的形式使用数组。
    注意:Delphi 4 的Object Pascal中增加了动态数组,所谓动态数组是在运行时动态分配内存改变数组大小。
    记录类型 
    记录类型用于定义不同类型数据项的固定集合。记录中每个元素,或者说域,有它自己的类型。记录类型定义中列出了所有域,每个域对应一个域名,通过域名可以访问它。
    下面简单列举了记录类型的定义、类型变量的声明以及这类变量的使用:
    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 记录类型的应用不符合类型安全原则,因此不提倡在编程中使用。 

    

 

相关新闻

每一个程序员要遵守的一些优秀编程风格
代词it, that, one, the one 的辨析
《VB程序设计基础》选择题
Is Family Life Changing
设计模式之Iterator
设计模式之Visitor
设计模式之Interpreter(解释器)
设计模式之Mediator(中介者)
设计模式之Strategy(策略)
设计模式之State

您可能对这些感兴趣  

第7讲 综合分析BIM在运用与推广中的障碍问题
考核学生质量的困难
日本福岛核电站事故初步分析
论科技异化与科技人化
中国科技计划项目管理现状与对策
财政科技资金的审计重点和内容
软科学研究机构在政府决策中的功效、困境及对策研究
打造超级DOS系统(下)
DOS命令基础应用(6)
打造超级DOS系统(上)

题目筛选器
日期:
类型:
状态:
得分: <=
分类:
作者:
职业:
关键字:
搜索

 
 
 
  焦点事件
 
  知识体系
 
  职业列表
 
 
  最热文章
 
 
  最多引用文章
 
 
  最新文章
 
 
 
 
网站介绍 | 广告服务 | 招聘信息 | 保护隐私权 | 免责条款 | 法律顾问 | 意见反馈
版权所有 不得转载
沪ICP备 10203777 号 联系电话:021-54428255
  帮助提示    
《我的太学》是一种全新的应用,您在操作中遇到疑问或者问题,请拨打电话13564659895,15921448526。
《我的太学》