Solaris 动态跟踪指南

第 6 章 字符串

DTrace 可以对跟踪和处理字符串提供支持。本章介绍用于声明和处理字符串的完整的 D 语言功能集。与 ANSI-C 不同,D 中的字符串具有自己的内置类型和运算符支持,以便您可以在跟踪程序中轻松而明确地使用这些字符串。

字符串表示

在 DTrace 中,字符串表示为由空字节(即,值为零的字节,通常写为 '\0')结尾的字符数组。字符串的可见部分的长度是可变的,具体取决于空字节的位置,但是 DTrace 将以大小固定的数组存储每个字符串,以便每个探测器跟踪一致的数据量。字符串的长度不能超过此预定义的字符串限制,但可以在 D 程序中或在 dtrace 命令行上通过调整 strsize 选项来修改该限制。有关可调整的 DTrace 选项的更多信息,请参见第 16 章。缺省字符串限制为 256 字节。

D 语言提供了显式 string 类型,而不是使用 char * 类型来引用字符串。string 类型与 char * 等效,因为它是字符序列的地址,但在将 D 编译器和 D 函数(如 trace())应用于 string 类型的表达式时,可提供增强功能。例如,在需要跟踪字符串的实际字节数时,字符串类型消除了 char * 类型的不确定性。在 D 语句中:

trace(s);

如果 s 属于类型 char *,则 DTrace 将跟踪指针 s 的值(即,跟踪一个整数地址值)。在 D 语句中:

trace(*s);

根据 * 运算符的定义,D 编译器将取消对指针 s 的引用并跟踪该位置的单个字符。对于处理设计用于引用单个字符或由字节大小整数(非字符串且不以空字节结尾)构成的数组的字符指针,这些行为很重要。在 D 语句中:

trace(s);

如果 s 属于 string 类型,则该 string 类型指示 D 编译器,需要 DTrace 跟踪字符地址存储在变量 s 中的以空字符结尾的字符串。也可以对 string 类型的表达式执行词法比较,如字符串比较中所述。

字符串常量

字符串常量引在双引号 (") 中,D 编译器自动为其分配 string 类型。您可以定义任意长度的字符串常量,该长度仅受系统中允许 DTrace 使用的内存数量的限制。结尾的空字节 (\0) 由 D 编译器自动添加到所声明的任何字符串常量中。字符串常量对象的大小是与字符串关联的字节数加上表示结尾空字节的一个附加字节。

字符串常量可能不含字面值换行符。要创建包含换行符的字符串,请使用 \n 转义序列来代替字面换行符。字符串常量也可包含任何为表 2–5 中的字符常量定义的特殊字符转义序列。

字符串赋值

char * 变量的赋值不同,字符串按值而不是按引用复制。字符串赋值使用 = 运算符进行,从源操作数中复制实际的字符串字节,直到包含变量左侧的空字节为止,该变量必须属于 string 类型。可以通过对变量分配 string 类型的表达式,来新建 string 类型的变量。例如,以下 D 语句:

s = "hello";

将新建一个 string 类型的变量 s,并将六个字节的字符串 "hello" 复制到该变量中(五个可列显字符和一个空字节)。字符串赋值与 C 库函数 strcpy(3C) 类似,不同之处在于,如果源字符串超出目标字符串的存储空间限制,则结果字符串将自动按此限制截断。

也可以为字符串变量分配与字符串类型兼容的表达式。在此情况下,D 编译器将自动提升源表达式为字符串类型,然后执行字符串赋值。D 编译器允许将 char * 类型或 char[n] 类型(即,任意大小的 char 类型的标量数组)的任意表达式提升为 string 类型。

字符串转换

使用强制类型转换表达式或应用 stringof 特殊运算符,都可以将其他类型的表达式显式转换为 string 类型,其含义等价:

s = (string) expression				s = stringof ( expression )

stringof 运算符紧密绑定到右侧的操作数。为了表达清晰,通常使用括号将表达式括起来,但并非严格要求这样做。

任何标量类型的表达式(如指针、整数、或标量数组地址)都可以转换为字符串。其他类型的表达式(如 void)不能转换为 string。如果将无效地址错误地转换为字符串,DTrace 安全功能将会阻止破坏系统或 DTrace,但您可能最后会跟踪一系列不可识别的字符。

字符串比较

D 过载二元关系运算符,并允许使用这些运算符进行字符串比较和整数比较。只要两个操作数均属于 string 类型,或一个操作数属于 string 类型而另一个操作数可以提升为 string 类型,则关系运算符就可以进行字符串比较,如字符串赋值中所述。所有关系运算符均可用于比较字符串:

表 6–1 用于字符串的 D 关系运算符

<

左边的操作数小于右边的操作数 

<=

左边的操作数小于或等于右边的操作数 

>

左边的操作数大于右边的操作数 

>=

左边的操作数大于或等于右边的操作数 

==

左边的操作数等于右边的操作数 

!=

左边的操作数不等于右边的操作数 

与整数一样,每个运算符计算为 int 类型的值,如果条件为 true,则该值等于 1,如果条件为 false,则等于 0。

关系运算符逐字节比较两个输入字符串,这与 C 库例程 strcmp(3C) 类似。每个字节使用 ASCII 字符集中的相应整数值进行比较,如 ascii(5) 中所示,直到读取空字节或达到最大字符串长度为止。以下是一些 D 字符串比较及其结果的示例:

"coffee" < "espresso"

... 返回 1 (true) 

"coffee" == "coffee"

... 返回 1 (true) 

"coffee" >= "mocha"

... 返回 0 (false)