dc unix:即使在同一數組索引處儲存新值後也保留初始值
我無法理解手冊頁中給出的這個例子
dc
:$ dc 1 0:a 0Sa 2 0:a La 0;ap 1
對我來說答案應該是 2,因為:
1 0:a
這裡我們將 1 儲存在 array 的第 0 個位置
a
。 2.0Sa
現在我們將 0 壓入 register 的堆棧
a
。 3.2 0:a
現在我們再次將 2 儲存在數組的第 0 個位置,a
從而覆蓋之前儲存在該位置的 1。 4.La
現在我們彈出儲存在寄存器堆棧中的 0
a
並將其推送到主堆棧。 5.0;a
現在我們再次將 0 推入主堆棧,然後將其彈出以用作數組索引,因此我們將儲存在數組第 0 位置的 2 推
a
入主堆棧。 6.p
現在我們列印主堆棧的頂部,即 2。所以答案應該是 2。
我錯過了什麼?
PS-我想
dc
用作標籤,但看起來它不存在,並且必須使用至少一個如此使用的標籤debian
(我的工作站作業系統)。
就像混合數組和堆棧一樣。在範例中,寄存器
a
既用作數組又用作堆棧。1 0:a 0 Sa 2 0:a La 0;a p
- 第一個
:a
寄存器a被視為一個數組。- 然後
Sa
- 寄存器a被視為堆棧。實際上,將數組從 pt 1. 向下推並創建一個新數組。As byman
:請注意,寄存器的每個堆疊實例都有自己的數組與之關聯。- then
:a
-register a被視為一個數組。將先前的值和第一個數組值向下推。- then
La
-register a被視為堆棧。要到達第一個堆疊的數組,就扔掉它,a[0]=2
因為它是一個數組。- then
;a
-register a被視為一個數組。現在只剩下一個值,添加到a的第一個數組值是1
。更多範例請參見答案底部。
根據評論:
«每個寄存器有多少個數組和堆棧?我以為一個寄存器有一個堆棧和一個單獨的數組。»
堆棧:
堆棧輸入
dc
是下推堆棧或 LIFO(後進先出)。和餐廳裡的盤子一樣。,------ pop / push - take / leave / | v [-----] top [-----] ... ... . [-----] [-----] [-----] .. (main) (register-a) (register-b) ...
我們有一個主堆棧或工作堆棧,除非指定了需要寄存器的操作,否則會使用它。每個寄存器都有自己的堆棧。
基本寄存器操作:
Sr
:從主棧中彈出一個值並將其壓入寄存器指定的棧中。兩個堆棧都修改了。r
Lr
:從指定的寄存器堆棧中彈出一個值r
並將其壓**入主堆棧。兩個堆棧都修改了。sr
:從主棧中彈出一個值並寫入寄存器。實際上更改由寄存器指定的堆棧中的最高值。如果該堆棧中沒有值 - 添加它。主堆棧修改。寄存器堆棧保留在更改的值旁邊。r``r
lr
:從寄存器中讀取r
值。如果有多個,則實際上是最高值。主要變了。寄存器堆棧保留。:r
:從主堆棧中**彈出兩個值,並使用第一個,最頂層,作為將第二個值儲存在寄存器中的數組中的位置的索引。主要變了。寄存器堆棧保留。r
;r
:從主堆棧中**彈出一個值,並將其用作從指定的寄存器中的目前數組讀取的索引。主要變了。寄存器堆棧保留。r
堆棧和數組混合
一種查看方式是成對的。當你開始時,所有的寄存器都是空的。當您通過 將元素添加到堆棧時
Sr
,您將隱藏該堆棧中的所有底層元素。說你這樣做:1 Sx 2 Sx 4 Sx x = (S) 4 VISIBLE (S) 2 HIDDEN (S) 1 HIDDEN
現在您可以更改寄存器x中的值,即;更改最頂部的元素 by
sx
,您可以通過lx
- 讀取,而無需更改堆棧中的元素數量:lx p # Read value in register x - in effect read topmost element from stack. 4 # Printed value by p. 3 sx # Change value in register x - in effect change topmost element in stack. x = (S) 3 VISIBLE (S) 2 HIDDEN (S) 1 HIDDEN
如果您決定添加數組元素,事情就會開始朝著更複雜的方向發展。
4 1:x 5 2:x x = [A] [2]=5 VISIBLE [1]=4 VISIBLE (S) 3 VISIBLE (S) 2 HIDDEN (S) 1 HIDDEN
現在我們已經將值添加到堆棧中的目前數組。我們可以讀取和修改任何VISIBLE元素。
44 1:x 55 2:x 33 sx 1;x p # Read and print index 1 44 lx p # Read and print stack top. 33 x = [A] [2]=55 VISIBLE [1]=44 VISIBLE (S) 33 VISIBLE (S) 2 HIDDEN (S) 1 HIDDEN
如果我們然後添加一個堆棧元素,一種方式可以說堆棧框架是不可擴展的,因為我們已將值添加到它上面的數組中。因此添加了一個新的堆棧幀。
6 Sx 7 Sx x = (S) 7 VISIBLE (S) 6 HIDDEN [A] [2]=55 HIDDEN [1]=44 HIDDEN (S) 33 HIDDEN (S) 2 HIDDEN (S) 1 HIDDEN
如果我們現在嘗試訪問最後一個數組,它會被隱藏。實際上,我們從一個空數組中讀取,結果是預設值
0
。我們可以將寄存器值7修改為sr
,但不能訪問向下兩層的數組,除非我們去掉上面的兩個堆棧元素。如果我們現在決定添加一些數組元素,它們將被添加到一個新數組中(作為成對數組),與頂部堆棧元素一起定位。
8 1:x 9 2:x x = [A] [2]=9 VISIBLE [1]=8 VISIBLE (S) 7 VISIBLE (S) 6 HIDDEN [A] [2]=55 HIDDEN [1]=44 HIDDEN (S) 33 HIDDEN (S) 2 HIDDEN (S) 1 HIDDEN
現在,如果我們彈出堆棧,我們會彈出7 ,但由於**中間有一個數組(可以這麼說),它也會被刪除。
Lx p # Pop + print top stack element. 7 # Value printed. x = (S) 6 VISIBLE [A] [2]=55 HIDDEN [1]=44 HIDDEN (S) 33 HIDDEN (S) 2 HIDDEN (S) 1 HIDDEN
8和9的數組消失了。值為6的堆棧元素是可見的。但是底層數組被阻塞了。通過
1;x p
yield 0讀取。在某種程度上,我們可以說堆棧元素是阻塞的,而數組是不透明的。數組有點掛在堆棧元素上。
我們需要再次從堆棧中**彈出以顯示底層堆棧元素 + 數組。
Lx p # Pop + print top stack element. 6 # Value printed. x = [A] [2]=55 VISIBLE [1]=44 VISIBLE (S) 33 VISIBLE (S) 2 HIDDEN (S) 1 HIDDEN
總之,可以說數組和堆棧的數量不限於每個寄存器一個。
–每個寄存器有多少個數組和堆棧?– 取決於您對該寄存器執行
多少次交替
Sr
和操作。:r
另一種看待它的方式是,只有一個堆棧但有多個數組,如果我們在添加數組元素之間添加堆棧元素……
另一種方式是說,在任何給定時刻,目前數組都不是
[register][array]
但
[register][stack-element][array]
這使:
[register][stack-element][array][...] [register][stack-element][array][1] [register][stack-element][array][0]
並且該
stack-element
部分是不透明的、只讀的等。儘管在這種情況下,我們還必須記住,我們不需要堆棧元素的值。可以只將數組值添加到寄存器。或者每個堆棧元素都與一個我們可以修改的零填充數組配對:
1 Sx 2 Sx 3 Sx 4 1:x 5 2:x 6 Sx 7 Sx 8 1:x 9 2:x x = (S) 7 + A[0]=0 A[1]=8 A[2]=9 A[3]=0 ... A[2048]=0 (S) 6 + A[0]=0 ... A[2048]=0 (S) 33 + A[0]=0 A[1]=4 A[2]=5 A[3]=0 ... A[2048]=0 (S) 2 + A[0]=0 ... A[2048]=0 (S) 1 + A[0]=0 ... A[2048]=0
希望它讓它更清楚一點。
一些例子
$ dc [ein] 0:a [zwei] Sa [drei] 0:a 0;ap # Copy + print index 0 of topmost array in register a drei Lap # Throws away [drei] and pops+prints first element in stack* zwei 0;ap # Copy + print index 0 of first array ein
$ dc [uno] 0:a # Array a(1) [dos] 1:a # Array a(1) [tres] 2:a # Array a(1) [cuatro] Sa # Array a(2) [cinco] Sa # Array a(2) [seis] Sa # Array a(2) [siete] 0:a # Array a(3) [ocho] 1:a # Array a(3) [nueve] 2:a # Array a(3) Laf # Throws away Array 3 to get to first stack array, Array 2. seis Laf cinco seis Laf cuatro cinco seis 2;af # Now we're at the first array, Array 1. tres cuatro cinco seis 1;af dos tres cuatro cinco seis 0;af uno dos tres cuatro cinco seis