Delphi 系统[18]关键字和保留字 record、packed -定义结构类型


Delphi 系统[18]关键字和保留字  record、packed -定义结构类型

1、定义:

  • record :定义结构类型。 一个结构体可以视为一个不需要实例化的类(某些地方和对象用法不同)。 
  • packed :用于对结构类型对象或数组类型对象进行打包,打包后的对象体积能显著减小。打包后元素对齐位置也会发生变化,不再对齐到与 CPU 处理能力相匹配的位置,因此打包后的对象,处理速度会降低。详细信息请查阅相关资料。 

2、示例:

{ 定义 record 类型 }
type 
  TMyRec = record 
    Name: string; 
    Age: Cardinal; 
    Sex: Boolean; 
  end; 
 
{ 定义 record 类型,用法类似于 class } 
type 
  TMyRec = record 
  private 
    FName: string; 
  public 
    procedure ShowResult; 
    property Name: string read FName write FName; 
  end; 
 
{ 实现 record 方法 } 
procedure TMyRec.ShowResult; 
begin 
  ShowMessage('调用成功!'); 
end; 
 
{ 调用 record 方法 } 
procedure TForm1.Button1Click(Sender: TObject); 
var 
  MyRec: TMyRec; 
begin 
  MyRec.Name := 'Record 测试'; 
  ShowMessage(MyRec.Name); 
  MyRec.ShowResult; 
end; 
 
---------------------------------------------------------------------------------------
{packed 打包 } 
{结构化类型的实例包含多个值。结构化类型包括集合、数组、记录和文件以及类、类引用和接口类型。除了只包含序数值的集合外,结构化类型可以包含其他结构化类型;类型可以有无限的结构层次。
默认情况下,结构化类型中的值在单词或双单词边界上对齐,以便更快地访问。当您声明结构化类型时,可以将保留字打包以实现压缩数据存储。}
type 
  { 未打包 } 
  TMyRecA = record 
    Name: string; 
    Age: Byte; 
    Sex: Boolean; 
  end; 
 
  { 打包 } 
  TMyRecB = packed record 
    Name: string; 
    Age: Byte; 
    Sex: Boolean; 
  end; 
 
  { 未打包 } 
  TMyArrayA = array [0 .. 32] of Byte; 
 
  { 打包 } 
  TMyArrayB = packed array [0 .. 32] of Byte; 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  ShowMessage(IntToStr(SizeOf(TMyRecA))); 
  ShowMessage(IntToStr(SizeOf(TMyRecB))); 
  ShowMessage(IntToStr(SizeOf(TMyArrayA))); 
  ShowMessage(IntToStr(SizeOf(TMyArrayB))); 
end; 
//使用压缩会减慢数据访问速度,对于字符数组,会影响类型兼容性(有关更多信息,请参阅内存管理)

3、有关 record 的一些说明:

record(类似于某些语言中的结构)表示一组异构元素。每个元素称为一个字段;记录类型的声明为每个字段指定名称和类型。

记录类型声明的语法为:

type 
    recordTypeName = record
        fieldList1: type1;
        ...
        fieldListn: typen;
end

其中recordTypeName是有效标识符,每个类型表示一个类型,每个fieldList是有效标识符或逗号分隔的标识符列表。最后的分号是可选的。

例如,下面的声明创建了一个名为TDateRec的记录类型:

type
  TDateRec = record
    Year: Integer;
    Month: (Jan, Feb, Mar, Apr, May, Jun, 
            Jul, Aug, Sep, Oct, Nov, Dec);
    Day: 1..31;
  end;
  • 每个TDateRec包含三个字段:一个名为Year的整数值、一个名为Month的枚举类型的值和另一个名为Day的介于1和31之间的整数。
  • 标识符Year、Month和Day是TDateRec的字段标识符,它们的行为类似于变量。

但是,TDateRec类型声明不为年、月和日字段分配任何内存;实例化记录时会分配内存,如下所示:

var Record1, Record2: TDateRec;

此变量声明创建TDateRec的两个实例,称为Record1和Record2。

通过使用记录的名称限定字段指示符,可以访问记录的字段:

Record1.Year := 1904;
Record1.Month := Jun;
Record1.Day := 16;

或使用with语句:

with Record1 do
begin
  Year := 1904;
  Month := Jun;
  Day := 16;
end;

现在,您可以将Record1字段的值复制到Record2:

Record2 := Record1;

因为字段指示符的作用域仅限于它出现的记录,所以您不必担心字段指示符和其他变量之间的命名冲突。

您可以使用记录而不是定义记录类型。。。直接在变量声明中构造:

var 
  S: record
  Name: string;
  Age: Integer;
end;

然而,这样的声明在很大程度上违背了记录的目的,即避免重复编码相似的变量组。此外,此类单独声明的记录将不具有分配兼容性,即使它们的结构相同。  

  

  

  

创建时间:2021.08.12  更新时间:

相关