Forth 循环求和数组返回类似于读取的地址,而不是正确的答案。为什么?
我试图制作一个程序,为我求一个数组的和,但当我尝试运行sum这个词时,它会不断给我一个非常长的数字,类似于一个地址。我试着把它拆开,在终端的字外一行一行地运行它,手动循环工作得很好,但当我去真正使它工作时,它完全失败了。我做错了什么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
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+
inUPLOAD
),覆盖了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 ;