美文网首页
Delphi 记录类型

Delphi 记录类型

作者: 寄居他乡 | 来源:发表于2019-07-23 16:06 被阅读0次

    Delphi 记录类型与函数参数传递

    Delphi记录类型

    type
      TRec = record       {定义结构 TRec}
        name: string[12];
        age: Word;
        nation:string;
      end;
      TPRec = ^TRec;      {定义 TRec 结构的指针类型 TPRec}
    
    type
      TRec = packed record       {定义结构 TRec}
        name: string[12];
        age: Word;
        nation:string;
      end;
      TPRec = ^TRec;      {定义 TRec 结构的指针类型 TPRec}
    

    Record 和Packed Record 第一种不带packed关键字的结构体表明编译器编译时要求进行字对齐,而第二种带packed关键字的结构体表明编译器编译该结构体时不需要进行字对齐,这种方式对结构体中的字段访问会比第一种方式慢!但是更节约空间。有Packed 的占用内存小,但是速度慢一点。没Packed 的占用内存大,但是速度快一点。

    结构中如果有string,最好通过string[]或者array of char方式, Delphi 在这里是把 string 当作 ShortString 用的.
    也就是说这里的 string 最大容量是 255 个字符, 127 个汉字。

    结构在使用时能用类代替就用类。因为以下几点:
    1、结构在栈分配地址,类在堆分配。在使用record类型声明一个变量的时候就已经在内存的栈为其分配了内存空间了。堆的空间比较灵活,也比较大。当然可以通过记录指针方式在堆中分配内存。
    如果只使用一个单结构指针, 用 New 分配内存是最合适的,

    var
      p: PPoint; {这是点结构 TPoint 的指针, 系统早定义好的}
    begin
      New(p);
    
    //  p^.X := 1; p^.Y := 2; {或者写成下面这样}
      p.X := 1; p.Y := 2;
    
      ShowMessageFmt('%d,%d', [p.X, p.Y]);
      Dispose(p);
    end;
    

    需要给一个结构指针分配更多容量; GetMem 可以很容易地完成这个任务, 关键是如何访问. 譬如:

    var
      p: PPoint;
    begin
      p := GetMemory(4 * SizeOf(TPoint)); {分配能容纳 4 个 TPoint 结构的内存}
    
      {下面的代码访问了第一个结构, 其他 3 个怎么访问呢?}
      p.X := 1; p.Y := 11;
      ShowMessageFmt('%d,%d', [p.X, p.Y]); {1,11}
    
      FreeMemory(p);
    end;
    
    //访问给结构指针分配的其他元素:
    var
      p: PPoint;
      buf: array[0..255] of Char;
    begin
      p := GetMemory(4 * SizeOf(TPoint)); {分配能容纳 4 个 TPoint 结构的内存}
    
      p.X := 1; p.Y := 11;
    
      Inc(p); {指向第二个结构}
      p.X := 2; p.Y := 22;
    
      Inc(p); {指向第三个结构}
      p.X := 3; p.Y := 33;
    
      Inc(p); {指向第四个结构}
      p.X := 4; p.Y := 44;
    
      {既然用了 Inc, 那么在释放或使用前, 必须把指针退回到起始点!}
      Dec(p, 3);
    
      {读出看看; 注意这里的 wvsprintf 也是格式化函数, 有时它更方便}
      wvsprintf(buf, '%d,%d; %d,%d; %d,%d; %d,%d', PChar(p));
      ShowMessage(buf); {1,11; 2,22; 3,33; 4,44}
    
      FreeMemory(p);
    end;
    

    简单方法

    var
      p: PPoint;
      i: Integer;
      buf: array[0..255] of Char;
    type
      ArrPoint = array of TPoint; {用于转换的自定义类型}
    begin
      p := GetMemory(4 * SizeOf(TPoint));
    
      for i := 0 to 3 do
      begin
        ArrPoint(p)[i].X := i;
        ArrPoint(p)[i].Y := i * i;
      end;
    
      wvsprintf(buf, '%d,%d; %d,%d; %d,%d; %d,%d', PChar(p));
      ShowMessage(buf); {0,0; 1,1; 2,4; 3,9}
    
      FreeMemory(p);
    end;
    

    2、RecList := array[0..100] of TRec;
    查找RecList[89] ,它需要将Rec中移动88个记录长度,由于Rec是不定长的,所以每次移动的长度也可能不相同,所以导致定位数组中记录体时定位时间长。
    3、如一定要使用记录体类型的,可以采用一些变通的方法,如采用数组指针,这样可以大幅提升性能,如针对前面的记录体数据情况,可以多定义一个指针变量,如下:

    PRecList = ^Rec
    RecList arrary[0..100] of PRecList
    

    这样定义相对的好处就是每次移动时,只需要移动记录指针的长度数即可,即在现有的windows系统中,只需要移动4位即可。指针每次都要分配空间,使用完再进行释放空间,操作难度比较大。

    相关文章

      网友评论

          本文标题:Delphi 记录类型

          本文链接:https://www.haomeiwen.com/subject/svkalctx.html