⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 book1.mdb

📁 不用说了!看看就明白了!
💻 MDB
📖 第 1 页 / 共 5 页
字号:
  所分配区域的大小由指针变量P的基类型决定。如果在应用程序堆栈中没有足够的内存空间供分配,将触发EOutOfMemory异常。如果程序不再需要该动态变量时,可以调用FreeMem标准例程释放为该变量分配的内存空间。
 程序示例如下:
Var F: file; 
Size: Integer;
Buffer: PChar;
begin
AssignFile(F, 'test.txt');
Reset(F, 1); 
try 
  Size := FileSize(F);
  GetMem(Buffer, Size);
  try 
   BlockRead(F, Buffer^, Size);
   ProcessFile(Buffer, Size);
  finally 
   FreeMem(Buffer);
  end; 
finally 
CloseFile(F);
end;
end;
  上例打开一个名字为test.txt的文件,并把文件读入动态分配的缓冲区,缓冲区大小为文件的大小,然后对文件进行处理,最后释放动态分配的缓冲区,并关闭文件。
  Pascal中有一个特殊的保留字nil,这是一个空指针常量,当指针的值为nil时,表示指针当前没有指向任何动态变量。值为nil的指针变量不能访问动态变量。
3.无类型指针
  无类型的指针是指指针变量在声明时没有指明基类型。无类型指针在声明中只使用Pointer。例如:
  var pAnyPoint:Pointer;
  指针pAnyPoint可以指向任何变量类型。无类型的指针的作用是它可以指向任何类型,但是,不能用指针变量符后加^的形式来引用它的动态变量。
4.字符指针类型
  字符指针类型即PChar数据类型,是一个指向以NULL(不是零)字符结尾的字符(Char)串的指针。这种类型主要用于与外部函数如在Windows API中所用的函数兼容。与Pascal字符串不同,Windows和C字符串没有一个长度字节。取而代之的是它们从0字节索引开始,以一个NULL(#0)结束。Pascal RTL字符函数根据长度决定存储在字符串变量中的字符数目。C函数实际上一次搜索字符数组的一个字符,直到碰到NULL,表示字符串结尾。在Windows API中所用的许多函数以指向NULL结束字符串或用NULL结束填入缓冲区的字符。在Pascal中使用这些函数就需要PChar类型变量。内存将分配给变量并被所需函数使用。
  除了PChar外,Delphi还包含PAnsiChar和PWideChar数据类型。
  PAnsiChar数据类型是一个指向以NULL(不是零)字符结尾的AnsiChar字符串的指针,在Delphi中,PCHAR等同于PAnsiChar。
 ?PWideChar数据类型是一个指向以NULL(不是零)字符结尾的WideChar字符串的指针,用于UniCode字符集。实际上,PAnsiChar和PWideChar数据类型的定义为:
type 
  PAnsiChar = ^AnsiChar;
  PWideChar = ^WideChar;
  PChar = PAnsiChar;
  字符串类型与PCHAR类型赋值兼容,即一个字符串可以直接赋给一个PCHAR类型的变量,例如:
  var P: PChar;
   ...
  begin 
  P := 'Hello world...';
  end;
  上面赋值语句首先申请一块区域,该区域包含字符串 'Hello world...',并在最后加上NULL,然后P指向这块内存区。上述例子等价于下列形式:
  const TempString: array[0..14] of Char = 'Hello world...'#0;
  var P: PChar; 
  ...
 begin 
  P := @TempString;
 end;
6.3.4 过程类型
  Object Pascal允许把过程和函数作为一个整体赋给变量和作为参数传递。实现这一功能的途径是使用Object Pascal的过程类型。
 声明一个过程类型的语法与声明过程或函数的首部的语法相似,不同的是声明一个过程类型时不需要过程或函数保留字后面的标识符。声明过程类型时可以指定一种调用约定方式,缺省的调用方式是Register。下面是声明过程类型的举例:
type 
TProcedure = procedure; 
TStrProc = procedure(const S: string);
TMathFunc = function(X: Double): Double;
  上例声明的三个过程类型中,第一个是不带任何参数的过程,第二个是带一个参数S的过程,第三个是带一个参数X的函数,函数返回值为Double。
  过程类型根据其是否运用于对象分为两类:全局过程指针和方法指针。
  声明过程类型时不带of Object的是全局过程指针。全局过程指针指向的是全局的过程或函数。例如上面的过程类型Tprocedure,TstrProc,TMathFunc都是全局过程指针。
  声明过程类型时带有of Object的是方法指针。方法指针指向的是一个对象的过程或函数方法。例如下面的过程类型是方法指针。
type TMethod = procedure of object;
TNotifyEvent = procedure(Sender: TObject) of object;
  声明过程类型变量的方法与声明其它类型变量的方法相同,下面例子声明两个过程类型变量:
var Proc:TProcedure; 
  StrProc:TStrProc;
  过程类型变量的值可以取下列四种之一:
 nil一个过程类型变量
 一个全局过程或函数标识符一个方法指示符下面举例说明过程类型的用法。
type TMainForm = class(TForm) 
  procedure ButtonClick(Sender: TObject);
  ...
  end;
var MainForm: TMainForm; 
  MathFunc: TMathFunc; 
  OnClick: TNotifyEvent;
function Tan(Angle: Double): Double;
  begin 
   Result := Sin(Angle) / Cos(Angle);
  end;
  上例的TMainForm是一个类类型,TMathFunc是前面定义的全局过程指针,TnotifyEvent是前面定义的方法指针。其中MathFunc和OnClick是两个过程类型变量。变量MathFunc和OnClick的赋值方式为:
  MathFunc := Tan;OnClick := MainForm.ButtonClick;
  调用结果为:
X := MathFunc(X);{等价于 X := Tan(X) }
OnClick(Self);{等价于 MainForm.ButtonClick(Self) }
  过程类型变量值等于NIL表示该过程类型变量没有赋值,因此在过程语句或函数调用中使用值等于NIL的过程类型变量将发生错误。防止的办法是使用Assigned()函数。例如:
  if Assigned(OnClick) then OnClick(Self);
  如果给定的过程类型变量已经赋值,Assigned函数返回TRUE,如果给定的过程类型变量值为NIL,Assigned函数返回FALSE。在把一个过程或函数赋给一个过程类型变量时要注意赋值兼容,必须满足下列条件:调用约定方式必须相同。?参数个数必须相同,相应的数据类型必须相同。?函数返回的值类型必须相同。
6.3.5 Variant数据类型
  Variant主要用于表达需要动态改变类型的数据。例如,当一个数据的实际类型在编译时不知道或运行时需要改变类型时,就可以使用Variant类型。
  Variant类型变量可以包含integer, real, string, boolean, 日期和时间等类型值或以及 OLE自动化对象等,还可以表示长度和维数可变的数组。
  Variant变量在首次创建时,总是被初始化为Unassigned。Unassigned是Variant变量的一个特殊值,表明Variant变量还未赋值,Variant变量的另一个特殊值是NULL,指示Variant变量未知或丢失数据。
6.4 数据类型的转换
  Object Pascal是一种类型严谨的程序设计语言,不是所有类型的数据都可以互相赋值的。只有赋值两边的数据类型一致或兼容才可以进行赋值操作。下面就有关数据类型兼容和强制数据类型转换等概念进行介绍。
6.4.1 类型兼容
  所闻类型兼容,是指一种类型的数据可以与另一种类型的数据进行关系运算。类型兼容是赋值兼容的前提条件,也是Object Pascal数据运算的基本前提。
?Object Pascal规定,只有满足下列条件才是类型兼容:
?两种类型都一致。
?两种类型都是实型。
?两种类型都是整型。
?一种类型是另一种类型的子界。
?两种类型都是另一种宿主类型的子界。
?两种类型都是另一种兼容基类型的集合类型。
?两种类型都是紧凑字符串类型,并具有相同的元素个数。
?一种类型是字符串类型,另一种类型是字符串类型、紧凑字符串类型或字符类型。
?一种类型是Pointer类型,另一种类型是任意的指针类型。
?两种类型都是类类型或,类引用类型,并且一种类型继承了另一种类型。
?一种类型是PChar类型,另一种类型是形式为array[0..X] of Char的字符数组。
?两种类型都是基类型相同的指针类型(编译开关$T设置为{$T+})。
?两种类型都是结果类型相同、参数个数相同、参数类型一致的过程类型。
?一种类型是Variant类型,另一种类型是整型、实型、字符串类型或布尔类型。
  当两个类型要进行关系运算操作而又不满足类型兼容时,将产生编译错误。 
6.4.2 赋值兼容
  类型兼容仅仅可以进行关系运算,只有赋值兼容的变量才可以赋值或进行参数传递。
  类型T2的值与类型T1的值赋值兼容是指T1和T2允许赋值操作,即:
  T1:=T2;
  Object Pascal规定,类型T1的值与类型T2的值赋值兼容必须有满足下列条件:
?T1和 T2类型相同,并且都不是文件类型或包含文件类型的自定义类型。
?T1是T2是兼容的有序类型,类型T2的值在类型类型T1的取值范围内。
?T1和 T2都是实型, 类型T2的值在类型T1的取值范围内。
?T1是实型,T2是整数型。
?T1和 T2都是字符串类型。
?T1是字符串类型,T2是字符类型。
?T1是字符串类型,T2是紧凑的字符串类型。
?T1是长字符串类型,T2是PChar类型。
?T1和T2是兼容的、紧凑的字符串类型。
?T1和T2是兼容的、集合类型。 类型T2的所有成员在类型T1的取值范围内。
?类型T2在类型T1的取值范围内。
?T1和T2是兼容的指针类型。
?T1是类类型,T2是T1的继承类类型。
?T1是类引用类型,T2是T1的继承类引用类型。
?T1是PChar类型,T2是字符串常量。
?T1是PChar类型,T2是形式为array[0..X] of Char的字符数组。
?T1和T2是兼容的过程类型。
?T1是过程类型,T2是具有与T1嗤

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -