我试图制作一个程序,为我总结一个数组,但是当我尝试运行单词sum时,它会继续给我一个类似地址的长数字。我尝试将它拆开并在终端中的字之外逐行运行并手动循环工作正常,但是当我真正使其工作时它完全失败。我做错了什么?
UIWindow
上传就像魅力一样,但我会在
之后使用这个词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
;
答案 0 :(得分:2)
因此,如果我理解正确,问题是:
我会做这样的事情:
: 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 .
答案 1 :(得分:1)
在UPLOAD
中执行LIST LENGTH @ CELLS ALLOT
。 ALLOT
在当前字典或数据空间指针处分配内存,而不必在LIST
返回的地址处分配内存。 ALLOT
不使用堆栈中的起始地址。实际上,上面代码片段中LIST返回的地址稍后会在数组填充循环中由!
使用。它是第一个阵列单元的数据。因此,您的地址就像SUM
返回的地址一样。
最好将CREATE
和ALLOT
放在一起。在创建LIST和执行ALLOT之间发生了一些字典添加。您的阵列单元格可能不在LIST指向的位置。
通常,变量不会消耗堆栈中的数字。大多数情况下,它们会自动初始化为0
。所以0 VARIABLE CUMSUM
将在堆栈上留下零。
如果你一次运行或输入代码,这会产生DEPTH
和LENGTH
的后果。
尽量避免DEPTH
,最好是明确告诉数组定义单词您想要多少项,例如:
CREATE LIST 3 CELLS ALLOT
BTW在SwiftForth中运行您的代码,我在SUM
的字典主菜之后分配了一个4单元格数组。我在LENGTH @ 1+
之后的字典中存储了5个项目UPLOAD
LIST
),覆盖了CUMSUM
字典主菜的部分...
Lars Brinkhoff展示了一个不错的选择,除了DEPTH
之外; - )
答案 2 :(得分:0)
主要问题是@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
你可以看到列表的第一个单元格是垃圾。所以也许upload
毕竟不是很好!
2)请注意,如果您只想在堆栈中添加所有值,则不需要使用变量来混淆命名空间:
: sum depth 1 do + loop ;