
マンページに提供されている例は理解できませんdc
。
$ dc
1 0:a 0Sa 2 0:a La 0;ap
1
私にとっては、次の理由で答えは2でなければなりません。
1 0:a
ここでは、配列の0番目の位置に1を格納しますa
。0Sa
これでレジスタスタックに0をプッシュしますa
。2 0:a
これで、配列のゼロ位置に2を再保存し、a
その位置に保存されている古い1を上書きします。La
次に、レジスタスタックに保存されているゼロをポップし、a
それをメインスタックにプッシュします。0;a
0をメインスタックにプッシュし、それをポップして配列インデックスとして使用するので、配列のゼロ位置に格納されている2をa
メインスタックにプッシュします。p
次に、メインスタックの一番上の2を印刷します。したがって、答えは2でなければなりません。
私は何を見逃していますか?
PS - ラベルとして使用したいがdc
存在しないようで、そのラベルdebian
(マイワークステーションOS)として使用されるラベルを少なくとも1つ使用する必要があります。
答え1
配列とスタックを混合するのと同じです。この例では、レジスタはa
配列とスタックの両方として使用されます。
1 0:a
0 Sa
2 0:a
La
0;a p
- 最初
:a
- 登録ㅏ考慮大量に。 - その後
Sa
- 登録ㅏスタックとして扱われます。効果的に配列を最初のポイントから下にスライドさせます。新しい大量に。のようにman
:レジスタの各スタックインスタンスには独自の連想配列があります。 - その後
:a
- 登録ㅏ考慮大量に。前の値と最初の配列値を下にスライドさせます。 - その後
La
- 登録ㅏ考慮山。拳を握る累積配列a[0]=2
配列なので廃棄してください。 - その後
;a
- 登録ㅏ考慮大量に。これで1つの値だけが残り、最初の配列値が追加されます。ㅏこれは1
。
回答の下部にある例をご覧ください。
コメントによると:
« レジスタごとにいくつのアレイとスタックがありますか?私はレジスタのためのスタックとは別の配列があると思いました。 »
スタック:
スタック入力はdc
プッシュダウンスタックまたはLIFO(後入選出)です。レストランの皿と同じです。
,------ pop / push - take / leave
/
|
v
[-----] top
[-----] ... ... .
[-----] [-----] [-----] ..
(main) (register-a) (register-b) ...
私たちは基本スタックまたは働くレジスタが必要なジョブが指定されていない場合、スタックが使用されます。各レジスタには独自のスタックがあります。
基本的な登録するタスク:
Sr
:人気のあるもの価値は次から来る基本スタックとプッシュそれはレジスタで指定されたスタックに移動しますr
。両方のスタックが修正されました。Lr
:人気のあるものr
およびで指定されたレジスタスタックの値プッシュ到着する基本山。両方のスタックが修正されました。sr
:人気のあるもの価値は次から来る基本スタックと書く登録できますr
。実際には、レジスタで指定されたスタックの最高値を変更しますr
。スタックに値がない場合は追加します。基本スタックが修正されました。レジスタスタック変更された値の横に残ります。lr
:読むレジスタの値ですr
。実際に複数の値がある場合は、最上位の値になります。基本変更されました。レジスタスタック保存してください。:r
:ポップアップが2つあります。価値は以下から来ています。基本スタックを積み重ね、最初の(上部)をインデックスとして使用して、配列の2番目の値をレジスタに保存しますr
。基本変更されました。レジスタスタック保存してください。;r
:人気のあるもの価値は次から来る基本スタックに格納し、それを指定されたレジスタの現在の配列から読み取った位置へのインデックスとして使用しますr
。基本変更されました。レジスタスタック保存してください。
スタックとアレイが一緒に混在する
観察する1つの方法はペアリングすることです。起動すると、すべてのレジスタが空になります。スタックに要素を追加するSr
と隠れるこのスタックのすべての基本要素です。次のようにすると仮定してください。
1 Sx
2 Sx
4 Sx
x = (S) 4 VISIBLE
(S) 2 HIDDEN
(S) 1 HIDDEN
今できる変化レジスタの値Xつまり、最上位要素を変更すると、スタック内の要素数を変更せずに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
今私たちは現在のスタックに配列。何でも読んで修正できます見える要素
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
もしそうなら、次へ追加要素を積み重ねる1つの方法は次のとおりです。スタックフレーム上記の配列にすでに値を追加しているため、拡張できません。したがって、新しいスタックフレーム追加されました。
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
が、上記の2つのスタック要素を削除しないと、2つのレベルより下の配列にアクセスできません。
いくつかの配列要素を追加することを決定すると、最上位のスタック要素を持つ新しい配列(ペアの配列として)に追加されます。
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
歩留まりで読む0。
ある意味では、配列が不透明である間にスタック要素がブロックされていると言えます。配列は少し似ています。にぶら下がってスタック要素に。
私たちがしなければならないことがもう1つあります。ポップミュージック~から山デフォルトのスタック要素+配列を表示します。
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
結論として、アレイとスタックの数はレジスタごとに1つに限定されないと言えます。
–各レジスタにはいくつのアレイとスタックがありますか?
- このレジスタで実行される代替合計Sr
演算の数によって異なります。:r
もう一つの観点では、スタックは1つだけですが、配列は複数あります。そして、もし配列要素を追加する間にスタック要素を追加します。
特定の瞬間に現在の配列がそうでないと言う別の方法があります。
[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
答え2
dc
これはコンパイラであることを覚えておく必要があります。そしてそれは信じられないほど古いコンパイラです。それは機械語、すなわちスタック指向の計算機です。非常に強力ですが、インターフェイスはユーザーを念頭に置いて設計されていません。すべてのユーザーフレンドリーを機械処理した後、他の言語で書かれた指示を効率的に処理するように設計されています。
dc
直感的な方法でデータを保存しません。dc
ものもの。新しい入力を読み取るとすぐに実行されない場合、値はスタックにスローされます。スタックのすべてのアイテムが下にプッシュされました。最新の項目が一番上、最も古いものが一番下に表示されます。最も古いスタックメンバーを検索するには、最新のスタックメンバーを処理する必要があります。
多くの人があまりにも多くを得る。結局、その山はそれほど奇妙ではありません。一種のランドリーバスケットと同じです。しかし、それはまた非常に一次元的であり、dc
それ以上です。
したがって、入力スタック、つまりメインスタックがあります。デフォルトでは、これはすべてのdc
コマンド入力と出力が行われる場所です。コマンドを発行すると動作します。しかし、他のすべてのレジスタもあります。少なくとも256個です。これらのそれぞれはそれ自体もスタックです。
[Ss]
通常、ave および[Ll]
oad コマンドを使用してレジスタを操作します。メインスタックの最上位値をスカラー値としてレジスタに保存するには、a
次の手順を実行しますsa
。その後、次のようにして、l
いつでもこのスカラー値をメインスタックの一番上にリロードできます。la
まあ、a
レジスタの現在のインスタンスが現在の状態に保たれていれば大丈夫です。
作る新しいa
親レジスタのスカラーインスタンス古い- スカラー値が保持されている場合 -Sa
このコマンドを使用すると、メインスタックをポップしてレジスタa
スタックをプッシュできます。とは異なり、la
このLa
コマンドはレジスタを破壊的にL
ロードします。このコマンドを使用してスカラー値をメインスタックにポップすると、そのレジスタインスタンスのすべてのエントリが破棄され、レジスタの以前のインスタンスに再度アクセスできます。
これも少し練習で簡単に学ぶことができます。これはメインスタックと同じですが、各レジスタに1つずつあります。ただし、各レジスタには配列と呼ばれる追加の次元があります。
各レジスタの各インスタンスの配列があります。基本サイズはそれぞれ2048個のインデックスだと思います。たとえスタックがどれほど深いのかよく疑問に思っており、かなり深いとしか言えません。レジスタの新しいスカラー値をインスタンス化すると、そのスカラー値だけでなく配列もプッシュダウンされます。新しいインスタンスには新しい配列があり、古いインスタンスの配列は変更されていないままで、新しいインスタンスをポップした後にスカラー値のようにアクセスできます。
配列インデックスへのアクセスは少しトリッキーです。まず、ほぼすべてのメインスタック操作は破壊的です。配列インデックスにアクセスする唯一の方法は、デフォルトのスタックからその値を取得してから呼び出すことです。この時点では、インデックス参照が破損しているため、覚えにくいです。インデックスカウンタを維持するのに役立ちo
ますO
。しかし、インデックス1または0を使用しないでください。
それにもかかわらず、レジスタ配列と対応するスタックは独立しておらず、相互依存的で多次元的である。練習と忍耐、少し超人的な決断力だけがあれば、素敵なことができます。頑張ってください。
答え3
私は同じ問題を抱えていましたが、マニュアルページ自体の例の周りのテキストを注意深く読み直すだけで十分でした。
:r Will pop the top two values off of the stack. The old sec-
ond-to-top value will be stored in the array r, indexed by
the old top-of-stack value.
;r Pops the top-of-stack and uses it as an index into the array
r. The selected value is then pushed onto the stack.
Note that each stacked instance of a register has its own array
associated with it. Thus 1 0:a 0Sa 2 0:a La 0;ap will print 1,
because the 2 was stored in an instance of 0:a that was later
popped.
ここで最後の段落はあなたの質問に正確に答えます。 2は0:aのインスタンスに保存され、ポップされます(Laがスカラー値をメインスタックのレジスタaに入れると自動的に削除されます)。