字符串
字符串
字符串类型种类
类型名 | 最大长度(字节) | 所需内存 | 说明 |
---|---|---|---|
ShortString | 255 | 2~256 字节 | 单字节字符组成的字符串(短) |
AnsiString | 2GB | 4字节~2GB | 单字节字符组成的字符串 |
WideString | 2GB | 4字节~2GB | 宽字节字符组成的字符串 |
UnicodeString | 2GB | 4字节~2GB | Unicode 字符组成的字符串 |
- 旧版本
Delphi
中,string
等价于AnsiString
- 新版本
Delphi
中,string
等价于UnicodeString
WideString 与 UnicodeString 基本无区别。
ShortString
ShortString 为短字符串,最大长度 255 字节的单字符字符串。相当于 array[0..255] of byte
。
短字符串通过索引去取字符时,应该从 1 算起,例如 str[1]
表示取首个字符,因为数组的 str[0]
表示字符串的实际长度。
- 可以通过
Length
函数获取短字符串的实际长度 - 也可以通过
str[0]
取数组首字节获取短字符串的实际长度
长字符串
长字符串 AnsiString
、WideString
、UnicodeString
都是位于 Heap 内存区。
AnsiString
和 UnicodeString
长字符串自带引用计数的额外信息,由运行时自动托管,当引用计数为0时,会自动释放内存。
AnsiString
AnsiString
由编译器在前面插入12字节(32位时)/24字节(64位时)的额外信息。
额外信息包括(1)代码页(2)字符的大小(3)引用计数(4)字符串长度
AnsiString
实际上是一个指针,真正的内容放在堆中,指向字符串的内容。实际上额外信息放在这个指针负索引的位置。
获取首字符请使用 AnsiString[1]
,因为 AnsiString[0]
还存放了字符长度,AnsiString[0]
不可获取。Low(AnsiString)
永远是 1。
额外信息:
32位下的指针偏移 | 64位下的指针偏移 | 字段说明 |
---|---|---|
-12 | -24 | 代码页(2字节) |
-10 | -22 | 字符大小(2字节) |
-8 | -16 | 引用计数 |
-4 | -8 | 字符串实际大小 |
0 | 0 | 字符串内容 |
UnicodeString
UnicodeString 是各字符为 UTF-16 的字符串。用法跟 AnsiString 差不多。也带引用计数,由运行时自动管理。
额外信息:
32位下的指针偏移 | 64位下的指针偏移 | 字段说明 |
---|---|---|
-8 | -16 | 引用计数 |
-4 | -8 | 字符串实际大小 |
0 | 0 | 字符串内容 |
String
是 UnicodeString
的别名。在旧版中,String
是 AnsiString
的别名。
WideString
跟 UnicodeString 差不多,但是没有引用计数,一般用于 COM 编程以兼容 BSTR。
UTF8String
UTF8String 其实是一种 AnsiString,请看下面声明方式,就能理解:
1 | Type |
UCS4String
UCS4String
是 UTF-32 字符的字符串,实现跟 UnicodeString 一样,只是每个字符是 4 字节。
旧版本的 UCS4String 只是声明为 array of UTF32Char
,新版本的 Delphi 是跟 UnicodeString 一样有各个方法成员和引用计数等。
NULL 结尾
C 语言的字符串是以 NULL 结尾的。 与 C 语言的 API交互,Delphi 中的兼容用法有:
- 利用索引从 0 开始的字符的数组来代替
- 采用字符的指针
PChar
或者PAnsiChar
,PWideChar
来代替
Delphi 会默认在字符串后面加 ‘\0’ 以兼容 C 。
字符指针
需要与 C API交互的话,对字符串指针的初始化可以直接使用字符数组或者字符串类型转换成字符指针:
1 | var |
- 可以通过
PChar()
、PWideChar()
、PAnsiChar()
强制类型转换获得跟 C 兼容的字符串指针,NULL字符结尾。 - 如果字符串为空字符串,则得到的指针为 nil
- Pointer(str) 强制类型转换可以得到无类型的指针。如果字符串为空字符串,同样得到的指针为 nil
注意:
- 通过
PChar()
等类型转换成字符指针 p 之后,可以通过 p 来更改字符串里面的字符 - 通过
PChar()
等类型转换成字符指针 p 之后,如果字符串变量被赋值更改,p 还是会指向旧字符串的原地址。
字符串、PChar
与字符数组之间的转换
1 | var |
1. 字符串到PChar
1 | // 字符串到 PChar |
2. PChar
到字符串
1 | // PChar 到字符串 |
3. PChar
到字符数组
1 | // PChar 到字符数组 |
4. 字符数组到 PChar
1 | // 字符数组到`PChar` |
5. 字符串到字符数组
字符串与字符数组之间的转换就只有通过 PChar
来中转
1 | StrCopy(@arr1, PChar(str1)); |
字符转义
转义单引号
字符串内连续两个单引号表示转义为一个单引号:
1 | str1 := 'I can''t do it.'; // I cann't do it. |
特殊字符
字符串内的特殊字符,在字符串中再用 ''
引起来,然后用 #
号来书写出 ASCII
码:
1 | str1 := 'Hello '#13#10' World'; // Hello \r\n World |
多行字符串字面量
Delphi 可以使用多行字符串的字面量,允许换行和里面包含各种字符。
使用三个单引号括起来,里面的所有字符都表示字符串内的内容:
1 | const |