Calculator

dc unix:即使在同一數組索引處儲存新值後也保留初始值

  • January 4, 2018

我無法理解手冊頁中給出的這個例子dc

$ dc  
1 0:a 0Sa 2 0:a La 0;ap  
1  

對我來說答案應該是 2,因為:

  1. 1 0:a

這裡我們將 1 儲存在 array 的第 0 個位置a。 2. 0Sa

現在我們將 0 壓入 register 的堆棧a。 3. 2 0:a 現在我們再次將 2 儲存在數組的第 0 個位置,a從而覆蓋之前儲存在該位置的 1。 4. La

現在我們彈出儲存在寄存器堆棧中的 0a並將其推送到主堆棧。 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
  1. 第一個:a寄存器a被視為一個數組
  2. 然後Sa- 寄存器a被視為堆棧。實際上,將數組從 pt 1. 向下推並創建一個數組。As by man請注意,寄存器的每個堆疊實例都有自己的數組與之關聯。
  3. then :a-register a被視為一個數組。將先前的值和第一個數組值向下推。
  4. then La-register a被視為堆棧。要到達第一個堆疊的數組,就扔掉它,a[0]=2因為它是一個數組。
  5. 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

89的數組消失了。值為6的堆棧元素是可見的。但是底層數組被阻塞了。通過1;x pyield 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

引用自:https://unix.stackexchange.com/questions/253519