turbopascal高级教程Word格式文档下载.docx
《turbopascal高级教程Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《turbopascal高级教程Word格式文档下载.docx(17页珍藏版)》请在冰豆网上搜索。
本章将讲述在程序设计时使用单元的技术、TURBOPASCAL与汇编语言和C语言混合编程技术、实现和使用动态数组的技术、编写中断例程的方法、在程序中使用扩展内存(EMS)和扩充内存(XMS)的方法以及将程序的标准数据作代码处理的方法等。
§
1.1单元及其使用
单元是能与TURBOPASCAL程序分开编译的一组TURBOPASCAL过程和函数。
因为单元是单独编译的,所以使用单元的程序编译速度快。
而且,一个独立的单元可以为多个程序使用。
充分利用单元的优点,不仅可以加快软件的开发速度,而且可以提高程序可维护性。
1.1.1单元的结构
一个单元有两部分组成──接口部分和实现部分。
如:
unit<
标识符>
;
{单元头}
interface{接口部分开始}
uses<
单元列表>
{可选项}
{公共说明部分}
implementation{实现部分开始}
{私有说明部分}
{过程或函数的定义}
begin{初始化部分开始}
{初始化代码}
end.
1.接口部分
单元的接口部分由保留字interface开始,在单元头和实现部分之间。
在此部分,说明公用的常量、类型、变量与过程和函数的头部。
一个程序如果使用了一个单元,那么它就能访问该单元的接口部分所定义的所有变量、数据类型、过程和函数。
接口部分仅包含过程和函数的头部。
过程和函数的实现部分在单元的实现部分定义。
在程序中使用一个单元只需要知道怎样调用单元中的过程,而不需要知道过程是怎样实现的。
2.实现部分
实现部分是由保留字implementation开始。
实现部分定义所有在接口部分声明的过程和函数的程序体。
另外实现部分可以有自己的说明,这些说明是局部的,外部程序是不知道它们的存在的,也不能调用它们。
因为在实现部分中声明的一切对象在作用域上是局部的,所以实现部分的改变对其它单元和程序来讲是不可见的。
因此,修改一个单元的实现部分,并不需要重新编译使用该单元的单元,只需要编译这个修改单元和使用此单元的程序。
然而,如果接口部分做了修改,所有使用该单元的单元和程序,均需要重新编译,甚至需要修改。
在实现部分,如果有uses子句,则必须紧跟在保留字implementation之后。
如果过程说明为external类型,则需用{$L文件名.OBJ}编译指令将其连入程序。
在接口部分说明的函数或过程,除了inline类型之外,都必须在实现部分再现,它们的头部必须和接口部分一致或用简写格式。
3.初始化部分
单元的整个实现部分通常包括在保留字implementation和end之间。
然而,如果把保留字begin放在end之前,在它们中间写一些语句,这些语句就是单元的初始化部分。
在初始化部分可以初始化任何变量,这些变量可由单元使用,也可通过接口部分由程序使用。
可以在这部分打开文件供程序使用。
例如,标准单元Printer用它的初始化部分使所有输出调用都指向文本文件Lst,这样在write语句中就可以使用它。
当使用单元的程序执行时,在程序的主体执行之前,它所使用的所有单元的初始化部分按uses子句中说明的先后依次被调用。
1.1.2单元的使用
当使用单元时,需在uses语句中将使用的所有单元的名字列出来,单元与单元之间用逗号(,)隔开。
usesdos,crt;
当编译器扫描到uses子句时,它把每个单元的接口信息加到符号表中,同时又把实现部分的机器码与程序代码连接起来。
1.单元的直接引用
一个模块(程序或单元)的uses子句只须列出该模块直接使用的单元名。
例如:
programprog;
usesunit2;
const
a=b;
begin
writeln('
a='
a);
unitunit2;
interface
usesunit1;
b=c;
implementaion
unitunit1;
c=1;
implementation
b=2;
unit2用了unit1,主程序用了unit2,间接地使用了unit1。
单元的接口部分如果有改动,则所有使用该单元的单元或程序必须重新编译。
但如果改动了单元的实现部分,则用到它的单元不必重新编译。
在上例中,如果unit1的接口部分改动了(如C=2),unit2就必须重新编译;
如果只改动实现部分(b=1),则unit2不必重新编译。
编译一个单元时,TURBOPASCAL计算出该单元的版本数,这个数是单元的接口部分的校验和。
上例中,在编译unit2时,unit1的当前版本数存入unit2的编译版本中,编译主程序时,unit1的版本数就和存在unit2中的版本数比较,若二者不同,说明unit2编译后,unit1的接口部分改动过,编译器给出错误信息并重新编译unit2。
2.单元的循环引用
由于在实现部分使用的单元对用户是不可见的,因此把uses子句放在单元的实现部分,进一步隐藏了单元的内部细节,而且有可能构造出相互依赖的单元。
下面的例子说明两个单元如何相互引用。
主程序Circular使用Display单元,而Display单元在接口部分说明了Writexy过程,它有3个参数:
坐标值x和y和要显示的文本信息,若(x,y)在屏幕内,Writexy移动光标到(x,y)并显示信息,否则,调用简单的错误处理过程ShowError,而ShowError过程反过来又调用Writexy来显示错误信息,这样就产生了单元的循环引用问题。
主程序:
programcircular;
uses
crt,display;
writexy(1,1,'
Upperleftcornerofscreen'
);
writexy(100,100,'
Wayofthescreen'
writexy(81-length('
Backtoreality'
),15,'
display单元:
unitdisplay;
procedureWritexy(x,y:
integer;
Message:
string);
usesCRT,Error;
procedureWritexy;
if(xin[1..80])and(yin[1..25])then
gotoxy(x,y);
writeln(message);
end
else
ShowError('
InvalidWritexycoordinates'
end;
Error单元:
unitError;
procedureShowError(ErrMessage);
usesdisplay;
procedureShowError;
Writexy(1,25,'
Error:
'
+ErrMessage);
Display和Error单元的实现部分的uses子句互相引用,TURBOPASCAL能完整编译两个单元的接口部分,只要在接口部分不相互依赖,在实现部分可以相互调用。
1.1.3单元与大程序
单元是TURBOPASCAL模块化编程的基础,它用来创建能够为许多程序使用但不需要源程序的过程和函数库,它是把大程序划分为多个相关的模块基础。
通常,一个大程序可以划分为多个单元,这些单元按过程的功能将其分组。
例如,一个编辑程序可以划分成初始化、打印、读写文件、格式化等若干个部分。
另外,也可以有一个定义全局常量、数据类型、变量、过程及函数的“全局”单元,它能被所有单元和主程序使用。
一个大程序的框架如下:
programEditor;
dos,crt,printer,
EditGlobal;
EditInit;
EditPrint;
EditFile;
EditFormat;
......
...
在大程序开发中使用单元的另一个原因是与代码段的限制有关。
8086处理器要求代码段长度最大为64K。
这意味着主程序及任何单元都不能超过64K。
TURBO PASCAL将每个单元放在一个单独的段中来解决这个问题。
1.2与汇编语言混合编程
TURBOPASCAL以编译速度快、生成的目标代码高速和紧凑而著称。
在大多数情况下,只使用TURBOPASCAL即可以完成各种各样的程序编制,但是,在硬件接口程序、实时控制程序及大规模浮点运算时,都需要用汇编语言来编程。
虽然TURBOPASCAL提供了INLINE语句和命令,以及内嵌式汇编语言(TURBOPASCAL6.00),但这是远远不够的。
本节详细讨论TURBOPASCAL与汇编语言混合编程的技术,