Delphi 常见类型的字节数,即delphi中各种类型占多少字节
下面把 Delphi 常见类型的字节数系统性列出来,并标注 32/64 位差异与 D2007 与 D2009+ 的差异点。单位均为字节,除非特别说明,记录对齐可能带来额外填充;packed record 取消填充。 整数与有序类型- ShortInt: 1
- Byte: 1
- SmallInt: 2
- Word: 2
- Integer: 4
- LongInt: 4
- Cardinal/LongWord: 4
- Int64: 8
- UInt64/QWord: 8
- NativeInt: 4(Win32)/ 8(Win64)
- NativeUInt: 4(Win32)/ 8(Win64)
布尔类型- Boolean: 1(true=1,false=0)
- ByteBool: 1(WinAPI 兼容,非 0 为真)
- WordBool: 2(WinAPI 兼容,-1 为真)
- LongBool: 4(WinAPI 兼容,-1 为真)
字符与字符串- AnsiChar: 1
- WideChar: 2
- Char:
- D2007 及之前:1(等于 AnsiChar)
- D2009+:2(等于 WideChar)
- ShortString: 1..256(长度字节1 + 实际字符字节数,上限 255)
- AnsiString: SizeOf(变量)= 指针大小(4/8),实际内容为动态分配(引用计数/长度在堆块头部)
- UnicodeString(D2009+): SizeOf(变量)= 指针大小(4/8),内容动态分配(UTF-16)
- WideString(BSTR): SizeOf(变量)= 指针大小(4/8),内容动态分配(UTF-16,非引用计数,COM 管理)
- String:
- D2007 默认等于 AnsiString,SizeOf(变量)= 指针大小(4)
- D2009+ 等于 UnicodeString,SizeOf(变量)= 指针大小(4/8)
注意:SizeOf(AnsiString/UnicodeString/WideString/动态数组/接口变量) 返回的是“引用(指针)大小”,不是实际数据大小。 浮点与定点- Single: 4
- Double: 8
- Extended:
- Win32: 10(80 位扩展精度)
- Win64: 8(和 Double 相同)
- Currency: 8(定点,4 位小数,缩放 10,000)
- Comp: 8(有符号 64 位整数,早期为定点用途)
- Real:
- 默认与 Double 等价(8);若 {$REALCOMPATIBILITY ON} 可能为 Real48(6),现代工程一般默认 8
- Real48: 6(老类型,不建议使用)
指针与引用类型- Pointer/PAnsiChar/PWideChar/PChar: 指针大小 4(Win32)/ 8(Win64)
- PByte/PWord/…:同指针大小
- Class 引用(TObject 等): 指针大小 4/8
- Interface(IUnknown/IDispatch/自定义接口): 指针大小 4/8
- 方法指针(procedure of object): 8(Win32,Data+Code 两个指针各 4)/ 16(Win64)
- 过程指针(procedure var): 指针大小 4/8
- THandle: NativeUInt(4/8)
时间/标识/颜色等常用类型- TDateTime: 8(实际上是 Double)
- TGUID: 16
- TColor: 4(Longint)
集合(set)与枚举(enum)- set of 子范围:大小 = ceil((MaxElemIndex+1)/8)
- 例:
- set of 0..7 → 1
- set of 0..15 → 2
- set of 0..31 → 4
- set of 0..255 → 32(上限)
- 枚举类型(type TEnum = (…);)默认大小随取值范围自动选择 1/2/4 字节
- 可用编译指令 {$Z1}, {$Z2}, {$Z4} 强制 1/2/4 字节大小
- 例:值范围 > 255 则至少 2 或 4
数组- 静态数组:大小 = 元素大小 × 元素个数
- 例:array[0..9] of Integer → 10 × 4 = 40
- 动态数组(TArray<T> 或 array of T):
- SizeOf(变量) = 指针大小(4/8),实际元素存放在堆上
- 开放数组参数(array of T)是编译器生成的参数传递机制,不作为独立类型计算 SizeOf
记录与类- record:大小 = 字段大小之和 +(可能的对齐填充)
- packed record 取消对齐填充(如你之前的 TSocketBuffer = packed record,大小为 4+4+2+4=14)
- class:
- 变量本身是指针(4/8)
- 实例对象在堆上:包含一条 VMT 指针(4/8)和各字段(以及对齐/填充),但通常不以 SizeOf(class type) 统计
变体- Variant/OleVariant: 16(VARIANT 结构体尺寸,存储类型 + 数据/引用)
其它说明与技巧- 对齐/填充:非 packed 记录中,编译器会按平台 ABI 对齐字段(例如 4/8 字节边界),导致 SizeOf 大于成员之和。
- {$MINENUMSIZE n}(或 {$Z1..4})可控制枚举最小存储字节数。
- Delphi 2009 起 Char/Widestring 语义变化(Char=WideChar,String=UnicodeString),要注意跨版本。
- 验证方法:可运行以下代码打印实际大小(以你编译器/平台为准)
- Writeln(SizeOf(Integer));
- Writeln(SizeOf(Extended));
- Writeln(SizeOf(String)); // 注意仅返回指针大小
- Writeln(SizeOf(TGUID));
复制代码
这里给出在 D2007 Win32 与 Delphi 11 Win64 下常见类型的精准字节数对照(以 SizeOf 为准)。说明:动态类型(String/动态数组/接口/类引用)用 SizeOf(变量) 返回的是“指针大小”,不是内容实际占用;record 默认会按平台对齐,packed record 则不填充。 D2007 Win32(32 位)- 指针/引用类
- Pointer/PChar/PAnsiChar/PWideChar:4
- 类引用(TObject 等):4
- Interface:4
- 过程指针(procedure var):4
- 方法指针(procedure of object):8(Code Ptr 4 + Data Ptr 4)
- THandle、NativeInt/NativeUInt:4
- 整数
- ShortInt/Byte:1
- SmallInt/Word:2
- Integer/LongInt:4
- Cardinal/LongWord:4
- Int64/UInt64(QWord):8
- 布尔
- Boolean:1(0/1)
- ByteBool:1(非 0 为真)
- WordBool:2(-1 为真)
- LongBool:4(-1 为真)
- 字符与字符串
- Char(=AnsiChar):1
- AnsiChar:1
- WideChar:2
- ShortString:1..256(1 字节长度 + 实际字符,最大 255 字符)
- String(=AnsiString):4(指针)
- AnsiString:4(指针)
- WideString(BSTR):4(指针)
- UnicodeString 默认为没有(D2009+ 才有)
- 浮点/定点
- Single:4
- Double:8
- Extended:10(80 位扩展精度)
- Currency:8(定点,×10000)
- Comp:8
- Real:通常等于 Double(8,除非开启 {$REALCOMPATIBILITY} 为 Real48)
- Real48:6(老类型)
- 时间/标识/颜色等
- TDateTime:8(Double)
- TGUID:16
- TColor:4
- Variant/OleVariant:16
- 枚举与集合
- 枚举:默认 1/2/4,取决于取值范围(可用 {$Z1|$Z2|$Z4} 强制)
- set of 0..N:ceil((N+1)/8);例如
- set of 0..7 → 1
- set of 0..15 → 2
- set of 0..31 → 4
- set of 0..255 → 32(上限)
- 数组与记录
- 静态数组:元素大小 × 个数
- 动态数组(array of T/TArray<T>):4(指针)
- record:字段之和 + 对齐填充(Win32 默认按 1/2/4 自然对齐);packed record 无填充(例如 packed record(4+4+2+4)=14)
Delphi 11 Win64(64 位)- 指针/引用类
- Pointer/PChar/PAnsiChar/PWideChar:8
- 类引用:8
- Interface:8
- 过程指针(procedure var):8
- 方法指针(procedure of object):16(Code Ptr 8 + Data Ptr 8)
- THandle、NativeInt/NativeUInt:8
- 整数
- ShortInt/Byte:1
- SmallInt/Word:2
- Integer/LongInt:4
- Cardinal/LongWord:4
- Int64/UInt64(QWord):8
- 布尔
- Boolean:1
- ByteBool:1
- WordBool:2
- LongBool:4
- 字符与字符串
- Char(=WideChar):2(Unicode)
- AnsiChar:1
- WideChar:2
- ShortString:1..256(同 Win32)
- String(=UnicodeString):8(指针,UTF‑16 数据在堆上)
- AnsiString:8(指针)
- WideString(BSTR):8(指针)
- UnicodeString:8(指针)
- 浮点/定点
- Single:4
- Double:8
- Extended:8(在 Win64 与 Double 等价)
- Currency:8
- Comp:8
- Real:8(等价 Double)
- 时间/标识/颜色等
- TDateTime:8
- TGUID:16
- TColor:4
- Variant/OleVariant:16
- 枚举与集合
- 枚举:默认 1/2/4,随范围({$Z1|$Z2|$Z4} 可强制)
- set of 0..N 大小规则同 Win32(上限 32 字节)
- 数组与记录
- 静态数组:元素大小 × 个数
- 动态数组:8(指针)
- record:字段之和 + 对齐填充(Win64 默认按 1/2/4/8 自然对齐,最大对齐通常为 8);packed record 无填充
重要差异与注意点- Char/String 语义:
- D2007:Char=AnsiChar(1),String=AnsiString(指针 4)
- D2009+(含 Delphi 11):Char=WideChar(2),String=UnicodeString(指针 8 在 Win64)
- Extended:
- Win32 为 10 字节;Win64 退化为 8 字节(与 Double 相同)
- 方法指针大小:
- 指针大小:
- Win32:4;Win64:8(影响 String/动态数组/接口/类引用/指针等 SizeOf)
- record 对齐:
- 非 packed 时,Win32 按 4 字节对齐常见;Win64 按 8 字节对齐常见,字段间可能插入填充导致 SizeOf 大于成员之和
- set/enum:
- set 最大 256 位(32 字节);enum 默认最小够用,或用 {$Z} 指令显式控制
快速自检(建议在你的工程里跑一遍)
- Writeln('Ptr=', SizeOf(Pointer));
- Writeln('Char=', SizeOf(Char), ' WideChar=', SizeOf(WideChar));
- Writeln('Integer=', SizeOf(Integer), ' NativeInt=', SizeOf(NativeInt));
- Writeln('Double=', SizeOf(Double), ' Extended=', SizeOf(Extended));
- Writeln('String(var)=', SizeOf(String)); // 指针大小
- Writeln('AnsiString(var)=', SizeOf(AnsiString));
- Writeln('UnicodeString(var)=', SizeOf(UnicodeString));
- Writeln('Method ptr=', SizeOf(TNotifyEvent));
- Writeln('Variant=', SizeOf(Variant), ' GUID=', SizeOf(TGUID));
复制代码
|