delphi基础篇之数据类型之二:2.字符串类型
2.字符串类型
2.1.ShortString
ShortString 又称为短字符串(相对的,Ansistring、widestring、unicodestring 称为长字符串),其实质上是一个编译器内置的字符数组,类似(不是等效)于以下类型:
Type
ShortString = array[0..255] of ansichar;
其容纳由 256 个 AnsiChar 组成的字符串,但第一个字符有特殊用途,所以 shortstring 类型的字符串长度不可超过 255byte。
ShortString 的第一个字节的值等于字符串的实际长度。故而获取 ShortString 字符串实际长度的方法有 2 种:
一是利用标准函数 Length();
二是直接利用第 1 个字节的值。
例如:
Var
Str;shortString;
Begin
Str := 'abcdefg';
Writeln(inttostr(integer(str[0]))); //显示 7
Writeln(inttostr(length(str))); //显示 7
End.
2.2AnsiString
AnsiString 类型也被称为长字符串。此类型的字符串由ASCII 扩展字符集组成。AnsiString 类型实质上是一个指针类型,指向字符串首个字符的地址,也就是第13个字节(delphi2009以后)。利用标准函数 Sizeof()可知此类型变量在内存中占用 4 个字节。为了节约内存,Delphi 将AnsiString 字符串的字符串本身分配在堆中,而在栈中留下一指向字符串的指针,这个指针就是 AnsiString 类型的变量。使用字符串索引时有两点值得注意:索引应当从 1 开始。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
A8 | 03 | 01 | 00 | FF | FF | FF | FF | 0F | 00 | 00 | 00 | 48 | 75 | 61 | 6E | 67 | 4A | 61 | 63 | 6B | 79 | 41 | 41 | 41 | 42 | 41 | 00 |
代码页 | 字符宽度 | 引用次数 | 字符串的字符数 | 字符串实际内容 | 结束符 | ||||||||||||||||||||||
936 | 1 | -1 | 15 | H | u | a | n | g | J | a | c | k | y | A | A | A | B | A | #0 | ||||||||
$03A8就是936, 查MSDN 936 - gb2312 |
每个字 符所占 的字节 数 (ANSI为1) |
对于常量字符串,引用计数总是-1,Delphi并未作出优化。当字符串为变量时计数大于等于1。 |
3.WideString
WideString 与 AnsiString 基本一样,除以下几点:
- WideString 没有引用计数
- 其中容纳由16bit unicode 字符组成的字符串
- 对于 WideString 类型的字符串索引会得到某个字符的值而非某个字节的值。
- 兼容于 COM 中的 BSTR 类型;实际上此类型最大的用途就在于此
4.UnicodeString
UnicodeString 与 AnsiString 基本相同,唯一的区别在于前者容纳的字符串由Unicode 字符集中的字符组成。事实上 UnicodeString 的出现更多是为了弥补 WideString在处理 Unicode 编码时的不足。在绝大多数场合,UnicodeString 比 WideString 更适合。但编写 COM 程序时,只能选择 WideString。注意对 unicodestring 字符串进行索引时得到的也是某个字符的值。
5.String
String 为 Delphi 的保留字,用作 UnicodeString 类型的一个别名。
- 在早期版本中如 Delphi7 当中包含编译指令{$H},当其处于{$H+}状态时 string 等价于Ansistring 类型;当其处于{$H-}状态时 string 等价于 shortstring 类型。Delphi2010 中此编译指令已被废弃,无论此指令处于何种状态 string 均等价于 UnicodeString。
- 作为 Delphi 的保留字,String 也用于声明自定义长度的 shortString 类型变量。默认情形下 shortString 类型的变量占用 256byte 的内存,我们可手动定义其占用的字节数:
- Var
- Mystr:String[n];
- Mystr 在内存中将只占 n+1 个字节。显然,N 的值不可超过 255。此声明相当于:
- Var
- Mystr:array[0..n] of ansichar;
6.UCS4String
USC4String 类型容纳 USC4 字符集中的字符组成的字符串。其声明如下:
type
UCS4String = array of UCS4Char;
此类型的字符串基本不用。在笔者看来,此类型现时只有两个用途:其一为方便Delphi 在未来迁移时花费最小的代价,毕竟 UCS4 编码是将来的趋势;其二是用于各种编码的字符串的转换,其它编码的字符串转化至 UCS4String 不会有任何的数据丢失,故而此类型很适合作为字符串转换时的中间格式。
7.CodePaged AnsiString
从前面的叙述可知 AnsiString 用于容纳扩展 ASCII 字符集字符形成的字符串。事实上,这种说法并不精确。较为精确的说法是:AnsiString 能够容纳所有编码格式的字符串,只要计算机上安装了相应的字符集,但只有 AnsiString 字符串的编码为本地扩展ASCII 字符集时才能被正确显示。
8.RawByteString
RawByteString 的原型为:
Type
RawByteString = type AnsiString($FFFF);
注意:$FFFF 不代表现有的任何编码方式。
使用 RawByteString 时注意:作为函数参数时,RawByteString 只能用作 const 或value 方式传递的参数,不可用于 var 方式传递。
9.Nul 结尾字符串
Delphi 不存在 C 风格的 NULL 结尾的字符串。作为替代,可以使用以下 2 种方法来模拟:
- 利用序数从 0 开始的静态字符数组代替字符串。
- 使用字符指针 PChar 与 PWideChar。
注意:使用字符数组替代字符串时应保证开启了{$X+}指令,此指令默认为开启状态。