Forth 循环求和数组返回类似于读取的地址,而不是正确的答案。为什么?

Forth 循环求和数组返回类似于读取的地址,而不是正确的答案。为什么?,forth,gforth,Forth,Gforth,我试图制作一个程序,为我求一个数组的和,但当我尝试运行sum这个词时,它会不断给我一个非常长的数字,类似于一个地址。我试着把它拆开,在终端的字外一行一行地运行它,手动循环工作得很好,但当我去真正使它工作时,它完全失败了。我做错了什么 variable length \ length var declared create list \ space for my list made 0 variable cumsum \ sum value initialized to zero : uplo

我试图制作一个程序,为我求一个数组的和,但当我尝试运行sum这个词时,它会不断给我一个非常长的数字,类似于一个地址。我试着把它拆开,在终端的字外一行一行地运行它,手动循环工作得很好,但当我去真正使它工作时,它完全失败了。我做错了什么

variable length \ length var declared
create list \ space for my list made
0 variable cumsum  \ sum value initialized to zero

: upload     ( n1 n2 n3 --) \ loops thru and stuffs data into array
depth        ( n1 n2 n3 -- n1 n2 n3 depth) \ get depth
length !     ( n1 n2 n3 depth -- n1 n2 n3) \ array length stored
list         ( n1 n2 n3 -- n1 n2 n3 addr)
length @     ( n1 n2 n3 addr -- n1 n2 n3 addr nlength)
cells allot  ( n1 n2 n3 addr nlength -- n1 n2 n3) 
length @ 1+  ( n1 n2 n3 -- n1 n2 n3 nlength) \ consume all entries
0            ( n1 n2 n3 nl -- n1 n2 n3 nl 0) \ lower loop parameter..
do           ( n1 n2 n3 nl 0 -- n1 n2 n3) \ loop begins
list         ( n1 n2 n3 -- n1 n2 n3 addr)
I            ( n1 n2 n3 addr -- n1 n2 n3 addr I) \ calculating address
cells        ( n1 n2 n3 addr I -- n1 n2 n3 addr Ibytes)
+            ( n1 n2 n3 addr Ibytes -- n1 n2 n3 addr1+)
!            ( n1 n2 n3 addr1+ -- n1 n2) \ storing into calculated address
loop
;
上传作品就像一个符咒,但之后我就去用这个词了

: sum ( n1 n2 n3 -- nsum)
upload \ initiates the array
length @  \ invokes upper limit of loop
0        \ lower limit of loop
do
list          ( -- addr)        \ addr invoked
I cells +     ( addr -- addr+)  \ offset calculated and added
@             ( addr+ -- nl)    \ registered value at address fetched
cumsum @      ( nl -- nl ncs)   \ cum sum value fetched to stack
+             ( nl ncs -- nsum) \ summation
cumsum !      ( nsum --)        \ new sum written to cumsum
loop
cumsum ?      ( -- cumsum)      \ show sum
;
它返回一个非常长的数字,看起来像一个地址,而不是我添加来测试它的一些小数字列表的总和

1  ok
2  ok
3  ok
sum 140313777201982  ok

因此,如果我理解正确,问题在于:

  • 将堆栈上的所有数字存储到数组中
  • 对数组中存储的所有数字求和
  • 我会这样做:

    : upload ( ... "name" -- ) create depth dup ,  0 ?do , loop ;
    : sum ( a -- n ) 0 swap @+ 0 ?do @+ rot + swap loop drop ;
    
    1 2 3 4 upload array
    array sum .
    
    这样使用:

    : upload ( ... "name" -- ) create depth dup ,  0 ?do , loop ;
    : sum ( a -- n ) 0 swap @+ 0 ?do @+ rot + swap loop drop ;
    
    1 2 3 4 upload array
    array sum .
    

    UPLOAD
    中执行
    LIST LENGTH@CELLS ALLOT
    <代码>分配在当前字典或数据空间指针处分配内存,而不必在
    列表
    返回的地址处分配内存<代码>分配不使用堆栈中的起始地址。实际上,
    稍后将使用上述代码段中返回的地址列表在数组填充循环中。这是第一个数组单元的数据。因此,
    SUM
    返回类似于地址的数字

    最好的方法是将
    创建
    分配
    放在一起。在创建列表和执行分配之间发生了一些字典添加。您的数组单元格可能不在列表所指向的位置

    通常,变量不使用堆栈中的数字。大多数情况下,它们会自动初始化为
    0
    。因此
    0变量CUMSUM
    将在堆栈上保留零。 如果您一次性运行或键入代码,则这与
    深度
    有关,因此与
    长度
    有关。 尽量避免
    深度
    ,最好是明确地告诉数组定义词您需要多少项,例如:
    创建列表3单元格分配

    顺便说一句,在SwiftForth中运行代码时,我在
    SUM
    的字典中心之后分配了一个4单元数组。我在
    列表
    之后的字典中存储了5项(
    LENGTH@1+
    in
    UPLOAD
    ),覆盖了
    CUMSUM
    的部分字典主旨


    拉尔斯·布林克霍夫(Lars Brinkhoff)展示了一个不错的选择,除了深度(即;-)

    主要问题正如@roelf所解释的那样。我只想补充两点

    1) 你怎么知道出了什么事?当您遇到这样的问题时,请检查内存-执行十六进制转储

    1 2 3 sum -1223205794  ok
    list 32 dump 
    B7175C58: 58 5C 17 B7  03 00 00 00 - 02 00 00 00  01 00 00 00  X\..............
    B7175C68: 00 00 00 00  00 00 00 00 - 5E 5C 17 B7  58 5C 17 B7  ........^\..X\..
     ok
    
    您可以看到列表的第一个单元格是垃圾。所以,也许上传的效果并不好

    2) 请注意,如果您只想在堆栈上添加所有值,则不需要在名称空间中添加变量:

    : sum depth 1 do + loop ;