Solaris 动态跟踪指南

指针和数组关系

就像在 ANSI-C 中一样,指针和数组在 D 中也有特殊关系。数组由与其第一个存储位置的地址关联的变量表示。指针也是具有所定义类型的存储位置的地址,所以 D 允许将 array [ ] 索引表示法与指针变量和数组变量配合使用。例如,以下两个 D 代码段的含义等价:

p = &a[0];				trace(a[2]);
trace(p[2]);

在左边代码段中,通过对表达式 a[0] 应用 & 运算符,指针 p 被赋给 a 中的第一个数组元素的地址。表达式 p[2] 将跟踪第三个数组元素(索引为 2)的值。因为 p 现在包含与 a 关联的同一地址,所以此表达式将生成与 a[2] 相同的值,如右侧代码段中所示。等价的一个后果就是 C 和 D 允许您访问任何指针或数组的任何索引。编译器或 DTrace 运行时环境不会执行数组界限检查。如果访问超出数组预定义值的内存,则会产生意外结果或者 DTrace 会报告无效地址错误,如先前示例中所示。与平常一样,不会破坏 DTrace 本身或操作系统,但您需要调试 D 程序。

指针与数组之间的区别在于:指针变量引用一个单独的存储块,该存储块包含另一存储空间的整数地址。数组变量会对数组存储空间本身命名,而不是对包含数组位置的整数位置命名。下图中显示了此区别:

图 5–2 指针和数组存储

该图显示了指向由 5 个对象组成的数组的指针。

如果尝试对指针和标量数组赋值,则 D 语法中将显示此区别。如果 xy 都是指针变量,则表达式 x = y 合法;表达式只将 y 中的指针地址复制到 x 命名的存储位置。如果 xy 是标量数组变量,则表达式 x = y 不合法。在 D 中不能将数组作为一个整体赋值。但是,可在允许使用指针的任何上下文中使用数组变量或符号名。如果 p 是指针而 a 是数组,则允许使用语句 p = a;此语句等价于语句 p = &a[0]