数组的PostScript复制运算符

时间:2015-03-31 12:15:10

标签: arrays postscript

我在PostScript中使用数组(或字典/字符串/...)时,正在寻找有关复制操作符的更多详细信息。

在PostScript语言参考手册中,我找到:

array1 array2 copy subarray2

在网站上我找到了这个例子:http://www.linuxfocus.org/English/July1999/article100.html

GS>[1 2 3] [4 5 6 7 8] copy pstack
[1 2 3]
GS<1>/ar [4 5 6 7 8] def
GS<1>[1 2 3] ar copy
GS<2>ar pstack
[1 2 3 7 8]
[1 2 3]
[1 2 3]
GS<3>

但是这个例子让我感到困惑,因为[1 2 3]和[1 2 3 7 8]。

现在复制操作符与数组的关系如何? 如果我有这个堆栈:

---------------top-
copy
[4 5 6 7 8]
[1 2 3]
------------bottom-

复制操作后什么停留在堆栈上?

只有子阵列?:

---------------top-
[1 2 3]
------------bottom-

或子阵列+数组2的一部分?:

---------------top-
[1 2 3 7 8]
------------bottom-

提前致谢。

1 个答案:

答案 0 :(得分:3)

从PostScript语言参考手册第3版,第548页,复制操作符:

  

&#39; ...在其他形式中,复制复制第一个的所有元素   复合对象进入第二个。复合对象操作数必须   具有相同的类型,除了可以将打包的数组复制到   数组(并且只能将数组副本复制到打包数组中,   因为它们是只读的)。这种形式的副本复制了a的值   复合对象。这与dup和其他运营商完全不同   只复制对象本身(参见第3.3.1节“简单和   复合对象“)。但是,复制只执行一个级别的复制。   它不会递归地应用于自身的元素   复合物体;相反,这些元素的价值变为   共享。

     

对于数组或字符串,第二个对象的长度必须为   至少和第一个一样伟大; copy返回初始子数组   或元素所在的第二个操作数的子串   复制。 array2或string2的任何剩余元素都不受影响。&#39;

在你的情况下,你(我认为)被引用复合对象的事实绊倒了。您需要根据指针或引用来考虑堆栈上的复合对象,而不是物理内存块。

因此,在第一个实例中,您创建了2个数组并在堆栈上放置指针,这些数组都没有指向它们的任何其他引用。然后执行复制。

复制操作符将第一个操作数指向的数组中的前3个元素复制到第二个操作数指向的数组中。然后它创建一个新的子数组,其中只包含已修改的元素。

然后从堆栈中删除2个数组,如果你认为它们是指针,它只是从堆栈中删除指针。由于这些数组未在其他任何地方引用,因此将释放内存。

最后,它在堆栈上放置了一个指向新数组的指针。 pstack解析指向数组的指针并打印生成的元素。

现在,在第二种情况下,您创建一个数组并从名称/ ar(将存储在当前字典中)引用它。然后创建第二个数组并在操作数堆栈上放置一个引用(指针),然后将引用放在&#39; ar&#39;在堆栈上。

接下来你打电话给副本。复制将前3个元素从初始数组复制到&#39; ar&#39;引用的数组。它还会创建一个新的子数组。然后它从操作数堆栈中删除对操作数的引用。由于初始数组现在未被引用,因此它被释放。但是,当前字典包含一个键&#39; / ar&#39;其值是对第二个数组的引用。所以我们不会释放与之相关的内存,它仍然被引用。最后,它将新的子阵列放在堆栈上

然后您将另一个引用添加到由&#39; / ar&#39;键入的数组中。在堆栈上再次调用pstack。 pstack解析数组引用并打印内容。

如您所见,复制更改了&#39; / ar&#39;引用的数组的前3个元素。并且还返回了包含复制元素的子数组。

注意:在原始示例中,第一个&#39;副本&#39;在堆栈上留下对包含[1 2 3]的数组的引用(由第一个pstack打印)。这就是为什么第二个pstack(在第二次执行复制之后)打印两次显然相同的数组,它不是,它打印引用到两个不同的子数组,每个子数组由一个执行的&#39返回;复制&#39 ;.所以而不是:

我们可以简单地完成:

GS>[1 2 3] [4 5 6 7 8] copy pstack
[1 2 3]
GS<1>/ar [4 5 6 7 8] def
GS<1> ar copy
GS>ar pstack
[1 2 3 7 8]
[1 2 3]
GS<2>

即我们采用第一个副本产生的[1 2 3]子阵列,并将其用作第二个副本的初始操作数。

请注意&#39; GS&#39; prompt有数字,表示操作数堆栈上的条目数。

所以,为了回答你的原始问题,没有保留在堆栈上,两个操作数都被删除,并且创建了一个新的子数组,并将它的引用放在堆栈上。