程序单元 编辑

程序单元是指在程序中执行某一特定任务的具有一定独立性的代码模块,类似于VB中的“过程”。

Delphi

编辑
Object Passal的程序结构很特殊,与其它语言如C++,Object Windows等结构都不同。一个Delphi程序由多个称为单元的代码模块组成。使用单元可以把一个大型程序分成多个逻辑相关的模块,并用来创建在不同程序中使用的程序库。

Program

编辑
Program单元就是Delphi中的项目文件。

Program单元是一个特殊的单元,类似于C语言中的Main程序,即为应用程序的主程序。一个程序可以有多个单元组成,也可以只有一个Program单元组成,例如前面我们介绍过的DOS窗口程序就只有一个Program单元组成。下面是一个典型的Program单元:program Project1;

uses Forms,

Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

begin

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

end

(1)程序首部指定程序名、以及参数等。

(2)Uses语句定义程序用到的所有单元。

标识符为单元的名字,各单元之间用逗好(,)隔开,最后结束用分号(;)。

注意:每个程序总是自动包含System单元,Program单元的Uses部分不能显式指定。System单元用于实现一些低级的运行时间程序的支持,如文件输入输出(I/O)、字符串操作、浮点运算、动态内存分配等。另外,Delphi在发行时提供了许多预先定义的单元,在构造程序时可以直接使用。例如,如果你将一个核对框放进一个窗体,你就自动地使用了StdCtrls单元,因为TCheckBox构件在StdCtrls中定义。

Uses部分列出单元的顺序决定它们初始化的顺序,并影响编译器定位标识符的顺序。如果两个单元定义了一个相同名字的类型,编译器将总是使用前面那个单元的类型。

(3)程序块由保留字Begin和End括起来的一段代码组成,用于对程序的初始化。

UNIT单元

编辑
UNIT单元相当于C语言的子程序。基本上Delphi每个窗体都一个对应的单元。当你为应用程序创建窗体时,你就创建了一个与该窗体相联系的新单元。然而,单元也可以独立于窗体而存在。例如,一个单元可以只包含数学运算程序,而不需要有窗体。

一个单元可以由多个程序共享。单元的磁盘文件名后缀为.pas。

单元结构

不管单元是否与窗体相关,单元的基本结构都是一样的 。UNIT单元由单元首部、接口部分(interface part)、实现部分(implementation part)、可选择的初始化部分(initialization part)、结束部分(finalization part)、end.组成。

单元首部

单元的首部用保留字Unit开始,后跟单元名。单元名必须遵循标识符的所有一般原则(不能以数字开头等)。下面的单元名将是有效的:

Unit Rsgl;

接口部分(Interface)

在单元名之后是接口部分。接口部分用于声明变量、类型、过程和函数等。在接口部分声明的变量、类型以及过程、函数等是其它使用该单元的程序或单元等都可见的。接口部分用保留字Interface标明开始,用implemention标明结束。接口部分只能含有声明部分。

一个单元的接口部分还作为该单元说明文件的起点。虽然接口部分没有告诉你子程序做什么或变量如何使用,但它正确告诉了你的变量、类型、过程、函数等的名字及其调用方法。

接口部分本身又可以由几个可选的部分组成,分别是单元的USES语句、常量声明部分、类型声明部分、变量声明部分、过程和函数声明部分。其中常量声明、类型声明、变量声明、过程和函数声明部分用于声明其它使用该单元的单元可以访问的变量、类型、过程和函数等。

而USES语句列出该单元要用到的标准单元和其它单元,用于把外部的已定义的常量、类型、变量、过程或函数引入到本单元中使用。USES语句紧跟在Interface之后。

实现部分

编辑
单元的第二部分,称为实现部分(Implementation),主要用于定义接口部分声明过的过程、函数等的代码。实现部分用保留字implementation标明,总是紧随接口部分之后。

实现部分也可以用USES语句列出该单元要用到的标准单元和其它单元等。如上面的uses MDIEdit;语句。实际上,实现部分也可以声明变量、数据类型、过程及函数等。

但是,在实现部分定义的变量、类型、过程、函数等只能由本单元自己使用(private declarations),使用该单元的其它单元或程序不可见的。私有定义可以隐藏单元的细节。

USES子句

编辑
USES子句用于访问其它单元。例如,如果你要让程序来效仿一个电传打字机,可以在USES包含WinCRT,因为WinCrt含有进行这个仿效所需要的程序。

USES WinCRT;

Delphi提供了许多预先定义的单元,你可以在程序中直接使用。实际上,当你将一个新构件放入设计的窗体时,DElphi会自动将该构件的单元放入USES子句中。例如,如果你将Color Grid放入窗体,则单元ColorGrd就附加在窗体单元的USES子句末尾,从而ColorGRd单元中接口部分所有定义都是窗体单元可以访问的。

要使用USES子句包含单元中的程序,只要在单元名后加上程序名即可。例如,如果要在Unit2中访问Unit1中的ComputePayMent函数。

USES子句可以放在接口部分(保留字Interface之后),也可放在实现部分(保留字Implementation之后),但是USES子句必须出现在它所有子程序、数据类型或变量被使用之前 。

USES子句放在实现部分可以隐藏单元的内部细节,同时可以避免循环引用发生。

初始化部分

编辑
初始化部分(Initialization)是单元的可选部分,主要用于对单元数据的初始化,一般很少用到。

该部分总是在其它程序代码之前运行。如果一个程序包含多个单元,则在程序的其它部分运行之前,每个单元的初始化代码都会先调用,其顺序是单元显示在Uses语句的顺序。

完成部分

编辑
完成部分(Finalization)是初始化过程的反过程,只要单元有初始化部分,才会有完成部分。完成部分对应在Delphi1.0中ExitProc和AddEXitProc函数。

完成部分在程序关闭时运行。任何在单元初始化时获得的资源如分配内存、打开文件等通常都在完成部分释放。单元完成部分的执行顺序与初始化部分相反。例如假如程序以A、B、C的顺序初始化单元,则完成过程的顺序是C、B、A。

一旦单元的初始化部分开始执行,就必须保证程序关闭时对应的完成部分执行。完成部分必须能够处理不完全初始的数据,因为如果产生异常,初始化代码可能不能完全执行。

程序单元结构

编辑
FORTRAN程序应由一个主程序单元和若干个过程程序单元组成。编程前应先作结构化分析,把问题分解为若干个子功能,每个子功能编成一个独立的程序单元,称为过程程序单元。再编一个主程序单元,控制整个解题过程。在主程序单元中用简练的形式调用每个过程,每次调用就是执行该过程单元,完成该子功能,从而最终完成解题任务。本章介绍F90中的程序单元、过程、范围、模块等概念。

模块

编辑
其中模块是F90新增加的一种程序单元。通过使用模块,可以方便地共享数据和过程。各种程序单元中,除主程序外,各程序单元可以被其他程序单元甚至自身调用。一个程序单元不需要包含可执行语句。包含内部子程序或函数的程序单元称为宿主程序。

主程序是程序开始执行的标志,其第一条语句不能是SUBROUTINE,FUNCTION,MODULE和BLOCK DATA。主程序可以用PROGRAM语句作为第一条语句,但不是必需的

过程

编辑
子程序或函数

块数据单元

在命名的公共块中提供变量初始值的程序单元

模块

包含数据对象定义、类型定义、函数或子程序接口和其它程序可访问的函数或子程序

程序单元之间的关系有:

联合:这种机制允许不同的程序单元共享变量,从而不用重新定义变量就可以以不同的名字处理同一数据。

范围:它描述的是一个名称(或者是全局的或者是局部的)作用的范围。

主程序

程序的执行始终是开始于主程序的第一条可执行语句,所以每个完整的Fortran程序必须有且仅有一个主程序。其形式为:

]

END ]

可以看到,主程序单元中允许包含内部过程。主程序名和外部过程名和公共块名都被认为是全局名称。全局名称在一个程序中必须是唯一的。

例:PROGRAM MAIN

REAL X(10),A(10,10),B(10) !说明部分

CALL GAUSS(A,B,X) !执行部分,调用内部过程GAUSS

CONTAINS

SUBROUTINE GAUSS(R,S,T) !内部过程的开始

END SUBROUTINE GAUSS !内部过程的结束

EHD PROGRAM MAIN

以下显示的是一个F90程序的标准结构。每条都可以是一个独立的源文件:

Program A1

Use module A

Call B

Contains

内部子程序

或内部函数

外部过程

如果过程是一个独立于主程序单元的程序单元,它就是外部过程。外部过程也可以通过非Fortran语言(通常是汇编语言)来定义。外部过程的形式有两种:

外部函数 :FUNCTION语句

END

外部子程序:SUBROUTINE语句

END

内部过程

内部过程是包含于外部过程、模块或主程序单元之中的程序单元。在宿主程序单元中,以CONTAINS语句把内部过程与其他部分分开。内部过程也具有两种形式:

内部函数 :FUNCTION语句

END

内部子程序:SUBROUTINE语句

END

注意内部过程中不能再包含内部过程,即F90不是过程嵌套式语言。

内在过程

内在过程是Fortran含于编译器程序库中的过程,它不需任何其它声明或说明即可使用。F90中定义了113个内在过程,它们为科学计算提供了极大方便,内在过程除了第一章中介绍的部分内在函数和第五章中介绍的部分数组函数外,还有其他一些内在函数及内在子程序,其具体使用方法请查看Visual Fortran的联机帮助。内在过程共分为四类:

(1)查询函数:它们的返回值是根据变元的性质而非变元的取值。

(2) 基本过程:由标量变元指明的基本过程,但可以用标量或数组实元进行调用。有许多函数是这种基本函数,并有一种基本内在子程序(MVBITS)。如果变元是标量,则结果也是标量。如果变元是数组,则对数组的每个元素施加过程,其结果是与变元形状相同的数组。例如,a是数组的话,则b=sin(a)也是数组。

(3)变换函数:其变元是数组,但过程不施加于每个元素,而是把变元变换成另一数组。

(4)非基本过程:只能以标量实元进行调用,除了MVBITS以外的所有内在子程序都是非基本过程。

如果要用内在过程名作为其它过程的实元,需要用INTRINSIC语句加以声明。

块数据

编辑
块数据单元是一种为有名公用块中的变量定义初始值的一种程序单元,它只包含数据声明和初始值,不包含可执行语句。其一般形式为:

BLOCK DATA

END ]

变量一般由DATA语句来初始化。公共块中命名的变量只能在块数据单元或某个过程中初始化一次,或只能由所有的过程完全一致地初始化。更好的编程法是用模块而不是块数据单元来声明和初始化变量。

在块数据单元的说明部分,不能包含ALLOCATABLE,AUTOMATIC,EXTERNAL,INTENT,OPTIONAL,PRIVATE或PUBLIC等属性说明符。

例:BLOCK DATA BLKDAT

INTEGER S,X

LOGICAL T,W

DOUBLE PRECISION U

DIMENSION R(3)

COMMON/AREA1/R,S,U,T/AREA2/W,X,Y

DATA R/1.0,2*2.0/,T/.FALSE./,U/0.214537D-7/,W/.TRUE./,Y/3.5/

END BLOCK DATA BLKDAT

下一篇 子程序

上一篇 详细设计