(delphi11最新学习资料) Object Pascal 学习笔记---第6章第2节(重温字符类型)

6.2 重温字符类型

​ 在介绍了 Unicode 之后,让我们回到本章的真正主题,即 Object Pascal 语言如何管理字符和字符串。我在第 2 章中介绍了 Char 数据类型,并提到了 Character 单元中的一些辅助函数。现在,你已经对 Unicode 有了更好的理解,值得重温这部分内容并进一步了解其中的细节。

​ 首先,Char类型并非总是代表Unicode码点。实际上,Char数据类型的每个元素使用2字节。虽然 Char 确实表示 Unicode 基本多语言平面(BMP)中元素的码点,但Char也可以是一对代理值的一部分,代表一个码点。

​ 从技术上讲,有一种不同的类型可以直接用于表示任何Unicode码点,这就是UCS4Char类型,它使用4字节来表示一个值。这种类型很少使用,因为通常很难证明所需的额外内存是合理的,但是,正如你很快会看到的,字符单元(接下来会介绍)也包含了对这种数据类型的一些操作。

​ 回到Char类型。请记住,这是一个序数类型,因此具有序列的概念,并提供了Ord、Inc、Dec、High和Low等代码操作。大多数扩展操作,包括特定的类型助手,不属于基本系统RTL单元,而是需要包含Character单元。

6.2.1 Character单元中的Unicode操作

​ 大多数Unicode字符(当然还有Unicode字符串)的具体操作定义在一个名为System.Character的特殊单元中。该单元定义了Char类型的TCharHelper类助手,允许您直接对该类型的变量应用操作。

注解: Character单元还定义了yige TCharacter记录,它基本上是一组静态类函数的集合,再加上一些映射到这些方法的全局例程。这些都是较老的、已弃用的函数。在Unicode级别上处理Char类型的首选方式是使用类助手。

​ 该单元还定义了两个有趣的枚举类型。第一个称为TUnicodeCategory,映射了各种字符的大类,如控制符、空格、大写或小写字母、十进制数字、标点符号、数学符号等。第二个枚举称为TUnicodeBreak,定义了各种空格(是的,空格不止一种)、连字符和分隔符的族。如果你习惯于 ASCII 操作,这将是一个很大的变化。首先,Unicode 中的数字不仅仅是 0 到 9 之间的字符;空格也不仅限于 #32 字符;256 元素字母表中的许多其他假设也是如此(简单得多)。

Char类型助手有40多个方法,包括许多不同的测试和操作,可用于诸如以下情况:

  • 获取字符的数值表示(GetNumericValue)。
  • 请求类别(GetUnicodeCategory)或检查字符是否属于各种类别(IsLetterOrDigit、IsLetter、IsDigit、IsNumber、IsControl、IsWhiteSpace、IsPunctuation、IsSymbol和IsSeparator)。我在前面的演示中使用了IsControl操作。
  • 检查字符是否为小写或大写(IsLower和IsUpper),或转换其大小写(ToLower和ToUpper)。
  • 验证它是否是UTF-16代理对的一部分(IsSurrogate、IsLowSurrogate和IsHighSurrogate),以及以各种方式转换代理对。
  • 将其转换为UTF32(ConvertFromUtf32和ConvertToUtf32)和UCS4Char类型(ToUCS4Char)。
  • 检查它是否是给定字符列表的一部分(IsInArray)。

​ 请注意,其中一些操作可以应用于整个类型,而不是某个具体变量。在这种情况下,您必须使用Char类型作为前缀调用它们,如下面的第二个代码片段所示。

​ 该演示的一个例子是调用大写和小写操作对 Unicode 元素的影响。事实上,RTL 的经典 UpCase 函数仅适用于 ANSI 表示法中的 26 个英语字符,而对某些具有特定大写表示法的 Unicode 字符则不起作用(并非所有字母都有大写表示法,因此这不是一个通用概念)。

​ 为了测试这种情况,我在 CharTest 示例中添加了以下代码段,尝试将重音字母转换为大写字母:

var
  Ch1: Char;
begin
  Ch1 := 'ù';
  Show('UpCase ù: ' + UpCase(Ch1));
  Show('ToUpper ù: ' + Ch1.ToUpper);

​ 传统的UpCase调用不会转换拉丁重音字符,而ToUpper函数可以正常工作:

UpCase ù: ù
ToUpper ù: Ù

​ Char 类型助手中有许多与 Unicode 相关的功能,例如下面代码中突出显示的功能,它将字符串定义为也包括 BMP(前 64K 个 Unicode 码点)以外的字符。该代码片段也是 CharTest 示例的一部分,对字符串的各种元素进行了一些测试,全部返回 True:

var
  Str1: string;
begin
  Str1 := '1.' + #9 + Char.ConvertFromUtf32(128) +
    Char.ConvertFromUtf32($1D11E);
  ShowBool(Str1.Chars[0].IsNumber);
  ShowBool(Str1.Chars[1].IsPunctuation);
  ShowBool(Str1.Chars[2].IsWhiteSpace);
  ShowBool(Str1.Chars[3].IsControl);
  ShowBool(Str1.Chars[4].IsSurrogate);
end;

​ 在这种情况下使用的显示函数是一个经过调整的版本:

procedure TForm1.ShowBool(Value: Boolean);
begin
  Show(BoolToStr(Value, True));
end;

注解:Unicode码点$1D11E是音乐G谱号符号。

6.2.2 Unicode字符字面量

我们已经在多个示例中看到,可以将单个字符字面量或字符串字面量赋值给字符串类型的变量。一般来说,使用带有 # 前缀的字符数字表示法非常简单。但也有一些例外情况。为了向后兼容,纯字符字面量会根据上下文进行转换。考虑以下对数值128进行简单赋值的代码,该数值表示使用欧元货币符号(€):

var
  Str1: string;
begin
  Str1 := #$80;

这段代码不符合 Unicode 标准,因为该符号的码点是 $8364 。事实上,这个数值并不是来自官方的 ISO 编码页,而是微软为 Windows 专门实现的。为了方便将现有代码移至 Unicode,Object Pascal 编译器可以将 2 位字符串字面量视为 ANSI 字符(这可能取决于你的实际编码页)。令人惊讶的是,如果将该值转换为字符,并再次显示,数字表示法将变为正确的表示法。因此,通过执行语句:

Show(Str1 + ' - ' + IntToStr(Ord(Str1[1])));

我将得到输出:

€ - 8364

如果你想完全移植旧代码,摆脱基于 ANSI 的字面值,可以使用特殊指令 `$HIGHCHARUNICODE` 来改变编译器的行为。该指令决定编译器如何处理 #$80 和 #$FF 之间的字面值。我前面讨论的是默认选项(OFF)的效果。如果将其打开,同样的程序将产生这样的输出结果:

◎ - 128

该数字被解释为一个实际的 Unicode 码点,输出将包含一个不可打印的控制字符。另一种表达该特定码点(或 #$FFFF 以下的任何 Unicode 码点)的方法是使用四位数符号:

Str1 := #$0080;

无论设置 $HIGHCHARUNICODE 指令与否,都不能将其解释为欧元货币符号。

注解:上述代码和配套演示仅适用于美国或西欧地区。对于其他地区,128 至 255 之间的字符会有不同的解释。

值得注意的是,您可以使用四位数符号来表示远东字符,例如以下两个日文字符:

Str1 := #$3042#$3044;
Show(Str1 + ' - ' + IntToStr(Ord(Str1.Chars[0])) +
  ' - ' + IntToStr(Ord(Str1.Chars[1])));

将以及它们的整数表示显示为:

あい - 12354 – 12356

您也可以使用超过 #$FFFF 的字面元素,它们将被转换为适当的代理对。

6.2.3 关于1字节Chars呢?

​ 正如我之前提到的,Object Pascal语言将Char类型映射到WideChar,但它仍定义了AnsiChar类型,主要是为了与现有代码兼容。一般建议对于一个字节的数据结构使用Byte类型,但是AnsiChar在进行一字节字符处理时的确很方便。

​ 在多个版本的Delphi中,AnsiChar在移动平台上并不可用,但从Delphi 10.4开始,这种数据类型在所有 Delphi 编译器上都能正常使用了。在将数据映射到平台的API或保存到文件时,通常应该避免使用旧的一字节Char类型,即使该类型受支持。到目前为止,使用 Unicode 编码是首选方法。不过,1 字节字符的处理速度确实比 2 字节字符更快,使用的内存也更少。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Object Pascal是一种强类型语言,对数据类型的定义、声明以及数据赋值和传递操作等有严格的语法规则。它的数据类型可以分为标准数据类型和高级数据类型,还支持自定义类型Delphi是一种基于Object Pascal的编程语言,用于桌面、移动、Web和控制台软件开发。它在1995年首次亮相之前的最初开发过程中,被称为一个未命名的产品的代号。 通过将数据库工具和连接性作为新的Pascal产品的核心部分,Delphi成为了一个强大的数据库产品,并成功挤压了Borland的Pascal工具在市场上与Visual Basic-C竞争的地位。这使得Delphi成为传统Windows开发工具中的领导者,并击败了微软在市场上的主导地位。123 #### 引用[.reference_title] - *1* [【2.Delphi语法基础】2.Object Pascal数据类型](https://blog.csdn.net/chenhaiy/article/details/122929788)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] - *2* *3* [2021年关于Delphi/Object Pascal编程语言的现状和历史](https://blog.csdn.net/xyzhan/article/details/119244320)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值