Delphi中的數據類型

以前一直使用的是Delphi 7,如今準備轉向Delphi XE7,聽說數據類型上有一些微小的調整,便想親自驗證一下,也順便加深一下本身對Delphi數據類型的認識,畢竟以前僅僅是在用而從未考慮過類型在內存中的形態。數組

驗證方法很簡單,就是在控制檯用Sizeof()把相應數據類型的字節數顯示出來。源碼以下:ide

program TypeSize;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  Emnu = (one, two, three, four);

  Range1 = $0..$FF;

  Range2 = $0..$FFFF;

  Range3 = $0..$FFFFFFFF;

  arr1 = array of Byte;

  arr2 = array[0..9] of Byte;

  arr3 = array[0..9] of Integer;

  rcd1 = record
  end;

  rcd2 = record
    b: Byte;
  end;

  rcd3 = record
    i: Integer;
  end;

  rcd4 = record
    i: Integer;
    j: Integer;
  end;

  rcd5 = record
    b: Byte;
    i: Integer;
  end;

  rcd6 = record
    r: Real;
  end;

  rcd7 = record
    r: Real;
    i: Integer;
  end;

  obj1 = object
  end;

  obj2 = object
    c: Char;
  end;

  obj3 = object
    i: Integer;
    o: obj2;
  end;

begin
  Writeln('   Type     | Bytes');
  Writeln('--------------------------------');
  Writeln('AnsiChar    = ', SizeOf(AnsiChar));
  Writeln('WideChar    = ', SizeOf(WideChar));
  Writeln('Char        = ', SizeOf(Char));
  Writeln('Byte        = ', SizeOf(Byte));
  Writeln('ShortInt    = ', SizeOf(ShortInt));
  Writeln('SmallInt    = ', SizeOf(SmallInt));
  Writeln('LongInt     = ', SizeOf(LongInt));
  Writeln('Int64       = ', SizeOf(Int64));
  Writeln('Byte        = ', SizeOf(Byte));
  Writeln('Word        = ', SizeOf(Word));
  Writeln('LongWord    = ', SizeOf(LongWord));
  Writeln('Integer     = ', SizeOf(Integer));
  Writeln('Cardinal    = ', SizeOf(Cardinal));
  Writeln('Boolean     = ', SizeOf(Boolean));
  Writeln('ByteBool    = ', SizeOf(ByteBool));
  Writeln('WordBool    = ', SizeOf(WordBool));
  Writeln('LongBool    = ', SizeOf(LongBool));
  Writeln('Single      = ', SizeOf(Single));
  Writeln('Real48      = ', SizeOf(Real48));
  Writeln('Double      = ', SizeOf(Double));
  Writeln('Extended    = ', SizeOf(Extended));
  Writeln('Comp        = ', SizeOf(Comp));
  Writeln('Currency    = ', SizeOf(Currency));
  Writeln('Real        = ', SizeOf(Real));
  Writeln('ShortString = ', SizeOf(ShortString));
  Writeln('AnsiString  = ', SizeOf(AnsiString));
  Writeln('WideString  = ', SizeOf(WideString));
  Writeln('String      = ', SizeOf(string));
  Writeln('Variant     = ', SizeOf(Variant));
  Writeln('Pointer     = ', SizeOf(Pointer));
  Writeln('--------------------------------');
  Writeln('Emnu        = ', SizeOf(Emnu));
  Writeln('Range(0,FF)       = ', SizeOf(Range1));
  Writeln('Range(0,FFFF)     = ', SizeOf(Range2));
  Writeln('Range(0,FFFFFFFF) = ', SizeOf(Range3));
  Writeln('Array()           = ', SizeOf(arr1));
  Writeln('Array(10)Byte     = ', SizeOf(arr2));
  Writeln('Array(10)Int      = ', SizeOf(arr3));
  Writeln('Record()                   = ', SizeOf(rcd1));
  Writeln('Record(1 byte)             = ', SizeOf(rcd2));
  Writeln('Record(1 int)              = ', SizeOf(rcd3));
  Writeln('Record(2 int)              = ', SizeOf(rcd4));
  Writeln('Record(1 byte, 1 int)      = ', SizeOf(rcd5));
  Writeln('Record(1 real)             = ', SizeOf(rcd6));
  Writeln('Record(1 real, 1 int)      = ', SizeOf(rcd7));
  Writeln('Object()                   = ', SizeOf(obj1));
  Writeln('Object(1 char)             = ', SizeOf(obj2));
  Writeln('Object(1 int, 1 obj(char)) = ', SizeOf(obj3));
  Readln;
end.

分別用Delphi 7和Delphi XE7編譯,運行結果如圖:測試

從運行結果能夠看出:編碼

  1. Delphi 7 和 Delphi XE7 數據類型的惟一區別就是默認的字符集發生的變化,Delphi 7 中 Char = AnsiChar,Delphi XE7 中Char = WideChar,即 Delphi 7 默認使用 ANSI 編碼,Delphi XE7 默認使用 Unicode 編碼。相應的,Delphi XE7 中 String = WideString,PChar = PWideChar。
  2. AnsiString、WideString、String 和 Pointer 同樣佔用 4B 的空間,說明,字符串類型的本質其實就是指針。因爲 Delphi 對字符封閉得很好,使用起來感受和整型、浮點型等沒有什麼差異,但畢竟仍是不同的,這是須要注意的(有關狀況我會在另外一篇中詳細說明)。
  3. 枚舉類型4個元素佔1B,其它數量時也是1B,說明枚舉類型實際存儲的是元素的索引,或者說枚舉類型的元素實際是對應索引值的一個別名。至於超過256個元素的狀況未進行測試,即枚舉類型元素上限未測。
  4. 子界類型與枚舉類型比較相似,當元素個數少於256時用1B存儲,超過256個時用2B,2B不夠時用4B(沒有3B的狀況),以此推測,4B不夠時將用8B、16B等。
  5. 靜態數組佔用的是連續的內存區域,其大小爲數組元素大小的總合;動態數組在未指定數組大小時只有4B,說明動態數組的本質也是指針(有關細節會同字符串一同說明)。
  6. 記錄類型的大小通常來講是其元素類型的大小*元素的個數,無元素時0B;若是元素類型不一致,元素類型統一按較大的類型的大小進行存儲(猜測是爲了方便尋址,拿空間換時間,提升運行速度)。
  7. Object類型是Delphi較早的一種類型,與記錄類型很相似,不一樣的是其佔用空間的大小爲其元素大小的總合。估計Object類型就是記錄類型的前身,而在記錄類型出現後也依然沒有消亡,想必僅僅是爲了兼容古老的程序吧。
相關文章
相關標籤/搜索