dc unix: 동일한 배열 인덱스에 새 값을 저장한 후에도 초기 값을 유지합니다.

dc unix: 동일한 배열 인덱스에 새 값을 저장한 후에도 초기 값을 유지합니다.

맨페이지에 제공된 예를 이해할 수 없습니다 dc.

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

나에게는 다음과 같은 이유로 대답은 2가 되어야 합니다.

  1. 1 0:a
    여기서는 배열의 0번째 위치에 1을 저장합니다 a.

  2. 0Sa
    이제 레지스터 스택에 0을 푸시합니다 a.

  3. 2 0:a 이제 배열의 0 위치에 2를 다시 저장하고 a해당 위치에 저장된 이전 1을 덮어씁니다.

  4. La
    이제 레지스터 스택에 저장된 0을 팝 a하고 이를 메인 스택으로 푸시합니다.

  5. 0;a
    이제 0을 다시 메인 스택에 푸시한 다음 이를 팝하여 배열 인덱스로 사용하므로 배열의 0 위치에 저장된 2를 a메인 스택에 푸시합니다.

  6. p
    이제 메인 스택의 맨 위인 2를 인쇄합니다. 따라서 답은 2가 되어야 합니다.

내가 무엇을 놓치고 있나요?

추신 - 레이블로 사용하고 싶지만 dc존재하지 않는 것 같으며 해당 레이블 debian(내 워크스테이션 OS)로 사용되는 레이블을 하나 이상 사용해야 합니다.

답변1

배열과 스택을 혼합하는 것과 같습니다. 이 예에서 레지스터는 a배열과 스택 모두로 사용됩니다.

1 0:a 
0 Sa 
2 0:a 
La 
0;a p
  1. 첫 번째 :a- 등록고려대량으로.
  2. 그런 다음 Sa- 등록스택으로 처리됩니다. 효과적으로 배열을 1번째 지점에서 아래로 밀어넣고새로운대량으로. 에서와 같이 man:레지스터의 각 스택 인스턴스에는 자체 연관 배열이 있습니다.
  3. 그런 다음 :a- 등록고려대량으로. 이전 값과 첫 번째 배열 값을 아래로 밀어 넣습니다.
  4. 그런 다음 La- 등록고려더미. 주먹을 쥐다누적 배열a[0]=2배열이므로 폐기하세요 .
  5. 그런 다음 ;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스택을 푸시할 수 있습니다. 와 달리 laLa명령은 레지스터를 파괴적으로 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에 넣으면 자동으로 삭제됩니다).

관련 정보