맨페이지에 제공된 예를 이해할 수 없습니다 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
이제 배열의 0 위치에 2를 다시 저장하고a
해당 위치에 저장된 이전 1을 덮어씁니다.La
이제 레지스터 스택에 저장된 0을 팝a
하고 이를 메인 스택으로 푸시합니다.0;a
이제 0을 다시 메인 스택에 푸시한 다음 이를 팝하여 배열 인덱스로 사용하므로 배열의 0 위치에 저장된 2를a
메인 스택에 푸시합니다.p
이제 메인 스택의 맨 위인 2를 인쇄합니다. 따라서 답은 2가 되어야 합니다.
내가 무엇을 놓치고 있나요?
추신 - 레이블로 사용하고 싶지만 dc
존재하지 않는 것 같으며 해당 레이블 debian
(내 워크스테이션 OS)로 사용되는 레이블을 하나 이상 사용해야 합니다.
답변1
배열과 스택을 혼합하는 것과 같습니다. 이 예에서 레지스터는 a
배열과 스택 모두로 사용됩니다.
1 0:a
0 Sa
2 0:a
La
0;a p
- 첫 번째
:a
- 등록ㅏ고려대량으로. - 그런 다음
Sa
- 등록ㅏ스택으로 처리됩니다. 효과적으로 배열을 1번째 지점에서 아래로 밀어넣고새로운대량으로. 에서와 같이man
:레지스터의 각 스택 인스턴스에는 자체 연관 배열이 있습니다. - 그런 다음
:a
- 등록ㅏ고려대량으로. 이전 값과 첫 번째 배열 값을 아래로 밀어 넣습니다. - 그런 다음
La
- 등록ㅏ고려더미. 주먹을 쥐다누적 배열a[0]=2
배열이므로 폐기하세요 . - 그런 다음
;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
:팝업이 2개가 뜹니다가치는 다음에서 비롯됩니다.기본스택을 쌓고 첫 번째(맨 위)를 인덱스로 사용하여 배열의 두 번째 값을 레지스터에 저장합니다r
.기본변경되었습니다.레지스터 스택저장해.;r
:인기있는 것가치는 다음에서 나온다기본스택에 저장하고 이를 지정된 레지스터의 현재 배열에서 읽은 위치에 대한 인덱스로 사용합니다r
.기본변경되었습니다.레지스터 스택저장해.
스택과 어레이가 함께 혼합됨
관찰하는 한 가지 방법은 쌍을 이루는 것입니다. 시작하면 모든 레지스터가 비어 있습니다. 스택에 요소를 추가 Sr
하면숨다이 스택의 모든 기본 요소입니다. 다음과 같이 한다고 가정해 보세요.
1 Sx
2 Sx
4 Sx
x = (S) 4 VISIBLE
(S) 2 HIDDEN
(S) 1 HIDDEN
이제 할 수 있다변화레지스터의 값엑스, 즉 으로 최상위 요소를 변경하면 스택의 요소 수를 변경하지 않고도 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
그렇다면 우리는다음에 추가요소를 쌓는 한 가지 방법은 다음과 같습니다.스택 프레임위의 배열에 이미 값을 추가했기 때문에 확장할 수 없습니다. 그러므로 새로운스택 프레임추가되었습니다.
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
. 레지스터 값을 수정할 수 있습니다7by 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
수율 로 읽기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
섹션은 불투명하고 읽기 전용입니다. 하지만 이 경우에는 스택 요소의 값이 필요하지 않다는 점도 기억해야 합니다. 레지스터에 배열 값을 추가하기만 하면 됩니다.
또는 각 스택 요소는 수정할 수 있는 0으로 채워진 배열과 쌍을 이룹니다.
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
로드합니다. 이 명령을 사용하여 스칼라 값을 메인 스택에 팝하면 해당 레지스터 인스턴스의 모든 항목이 파괴되고 레지스터의 이전 인스턴스에 다시 액세스할 수 있습니다.
이것은 또한 약간의 연습으로 쉽게 익힐 수 있습니다. 이는 메인 스택과 같지만 각 레지스터마다 하나씩 있습니다. 그러나 각 레지스터에는 배열이라는 추가 차원이 있습니다.
각 레지스터의 각 인스턴스에 대한 배열이 있습니다. 기본 크기는 각각 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에 넣으면 자동으로 삭제됩니다).