Delphi 是強類型靜態語言,賦值符 := 要求左右類型**嚴格兼容**。不同於 C/C++ 隱式轉換,Delphi 需顯式調用轉換函數/類型轉換運算符,否則編譯報錯 「Type mismatch」 或運行時觸發範圍檢查錯誤。
| 目標類型 | 函數/語法 | 示例 | 說明 |
|---|---|---|---|
| Integer | Integer(expr) / Trunc/Round | Integer('A') = 65 | 字符/枚舉/布爾 → 序數值。浮點截斷取整。 |
| Char | Char(code) | Char(65) = 'A' | 序數值 → 字符 (AnsiChar/WideChar 視編譯器版本)。 |
| Boolean | Boolean(expr) | Boolean(0)=False, Boolean(1)=True | 0→False,非0→True。同 WordBool/LongBool (2/4 字節)。 |
| String (10進制) | IntToStr(int) | IntToStr(15) = '15' | 整數 → 字符串。 |
| String (16進制) | IntToHex(int, digits) | IntToHex(15,4) = '000F' | 固定寬度十六進制。 |
| Pointer → Integer | Integer(@Var) / PtrInt(@Var) | Integer(@Buffer) | 地址轉整數。64位用 NativeInt/PtrInt。 |
// 32位長整型拆分
HiWord(LongintVar) // 高 16 位 (Word)
LoWord(LongintVar) // 低 16 位 (Word)
// 16位整型拆分
HiByte(IntegerVar) // 高 8 位 (Byte)
LoByte(IntegerVar) // 低 8 位 (Byte)
// 指釖/地址拆分 (16位段:偏移模式,僅實模式/兼容層相關)
SelectorOf(Pointer) // 段選擇子 (高 16 位)
OffsetOf(Pointer) // 偏移量 (低 16 位)
// 合成指釖 (實模式巨型指釖)
Ptr(Seg, Ofs: Word) // 相當於 C 的 MK_FP(Seg, Ofs)
// 實際應用:讀取 Windows 內部 Task Database 結構
var P: PByte; Ch: Char;
P := Ptr(GetCurrentTask, $FA); Ch := Char(P^); // 'T'
P := Ptr(GetCurrentTask, $FB); Ch := Char(P^); // 'D'
| 類型 | 長度存儲 | 終止符 | 賦值方式 | 下標 0 含義 |
|---|---|---|---|---|
string (AnsiString/UnicodeString) | 隱式 (引用計數、長度字段) | **自動管理**,通常以 #0 結尾 (供 API 用) | s := 'abc' | 不可訪問 (編譯錯誤) 或返回長度 (舊版 ShortString) |
array[0..N] of Char | 無 | **手動** 需以 #0 結尾 | StrPCopy(arr, 'abc') 或逐字符賦值 | 第一個字符 |
array[1..N] of Char | 無 | **手動** 需以 #0 結尾 | StrPCopy(@arr[1], 'abc') | 越界 (無效) |
PChar (^Char) | 無 | 指向以 #0 結尾的緩衝區 | p := @str[1] (舊版) / PChar(str) (新版) | 指向首字符 |
StrPCopy(Dest: PChar; Source: string): PChar:複製字符串到緩衝區,**自動添加 #0 結尾**。返回 Dest。StrPas(Source: PChar): string:從 #0 終止的 PChar 複製到新 string。PChar(string) (Delphi 2009+):獲取字符串內部緩衝區指針 (只讀),已保證 #0 結尾。string(PChar):從 PChar 創建 string (按 #0 截斷)。// 錯誤 1: 直接將 string 當 PChar 用且未確保 #0 結尾 (舊版 ShortString)
var s: string; p: PChar;
s := 'new'; p := @s[1]; // s[0] 存長度 3,內存為 'n','e','w' 無 #0
ShowMessage(StrPas(p)); // 讀越界,亂碼或崩潰
// 正確 1: 手動加 #0 (舊版技巧)
s := 'new' + #0; p := @s[1]; // 內存: 'n','e','w',#0
ShowMessage(StrPas(p)); // 正常
// 正確 2: 用 StrPCopy 自動加 #0
StrPCopy(@s[1], 'new'); // s 變為 'new'#0, 長度 4
ShowMessage(StrPas(@s[1]));
// 正確 3: Delphi 2009+ 直接用 PChar(s)
var s: string; p: PChar;
s := '新'; p := PChar(s); // 內部緩衝區已有 #0
ShowMessage(string(p)); // 正常
// 字符數組陷阱
var a: array[1..10] of Char; b: array[0..10] of Char;
StrPCopy(@a[1], 'abc'); // 正確,@a[1] 是首字符地址
StrPCopy(a, 'abc'); // 錯誤!a 退化為指針指向 a[1]? 實際 a 是整個數組地址,類型不匹配
StrPCopy(b, 'abc'); // 正確,b 即 @b[0]
StrPCopy(@b[0], 'abc'); // 正確,等價
string = UnicodeString (UTF-16),Char = WideChar (2 字節)。PChar = PWideChar。Windows API 調用優先用 W 版 (MessageBoxW) 直接傳 PChar。AnsiString/UTF8String/RawByteString,配合 TEncoding 轉換。SizeOf(Char) = 2,Length(s) 返回字符數 (碼元數),字節長度 = Length(s) * SizeOf(Char)。for c in s do ... (c: Char) 或 for i := 1 to Length(s) do s[i]。**勿用字節偏移訪問**。TEncoding 或 AnsiString 類型標記。PByte/Pointer 做字節運算,避免 PChar 因字符大小導致錯誤偏移。Format/TStringBuilder,避免隱式轉換驚喜。{$R+} 捕獲數組越界、數值溢出。釋放版關閉提速。Delphi 類型轉換的核心在於**「顯式、精確、語義清晰」**。掌握 Integer/Char/Boolean 序數轉換、Hi/Lo 位拆分、string/PChar/CharArray 內存模型差異、StrPCopy/StrPas 橋接函數、以及 Unicode 時代的新類型映射,即可從容應對 99% 的類型轉換場景,編寫安全、高效、可移植的 Delphi 代碼。