我关注example,试图向自己解释它的作用:
: place \ ptr len ptr2
2dup \ ptr len ptr2 len ptr2
>r >r \ ptr len ptr2
char+ \ ptr len (ptr2 + 1)
swap \ ptr (ptr2 + 1) len
chars \ ptr (ptr2 + 1) (len * char)
cmove \ --
\ from to how-many
r> r> \ ptr2 len
c! ; \ len = ptr2 ???
\ s" Hello! " name place
这一切都有道理,直到最后一条指令......我哪里出错?
修改
我添加了一些跟踪:
: place \ ptr len ptr2 |
2dup cr .s \ ptr len ptr2 len ptr2 | <5> 16490736 5 2126333248 5 2126333248
>r >r cr .s \ ptr len ptr2 | <3> 16490736 5 2126333248
char+ cr .s \ ptr len (ptr2 + 1) | <3> 16490736 5 2126333249
swap cr .s \ ptr (ptr2 + 1) len | <3> 16490736 2126333249 5
chars cr .s \ ptr (ptr2 + 1) (len * char) | <3> 16490736 2126333249 5
cmove cr .s \ -- | <0>
\ from to how-many |
r> r> cr .s \ ptr2 len | <2> 5 2126333248 ok
c! ; \ ptr2 = len ??? |
\ s" Hello! " name place
答案 0 :(得分:1)
因此,对于字符串“HELLO”,字节看起来像
05 H E L L O
字符串的开头指向字节,其中包含5。
你的代码找到了字符串,跳过了长度(第一个char+
),然后为cmove
填充它,这就完成了工作。
最后,它将长度复制到新String的开头。
例如,使用place
是错误的,因为您没有指定副本的长度。这需要长度作为堆栈的第二个参数。
所以,你的例子应该是:
s" Hello! " 7 name place \ 7 because of the space after the Hello!, the quote is the
\ delimiter, not the space. The leading spaces are ignored
关于这一点的奇怪之处在于理论上没有必要将长度传递给单词,它已经存在于String中。如果要复制子集,可以指定长度。
你也可以这样看待它。鉴于place
原样,你可以写一个简单的词:
: copy-string ( string-src dest -- )
>r \ string-src
dup \ string-src string-src
c@ \ string-src length
<r \ string-src length dest
place ;
所以:
s" Hello! " name copy-string
然后,你可以这样做:
: type-string ( string-src )
dup \ string-src string-src
c@ \ string-src length
type ; \ type out the string, type requires addr and length
所以:
create name 10 allot
s" Hello! " name copy-string
name type-string
答案 1 :(得分:1)
我认为Will Hartung的答案的第一部分是正确的。
正在使用的字符串表示符如他所描述的,即字符计数,然后是实际的字符串。
因此,在您的示例c!
中,将字符串的长度存储在以ptr2
开头的内存的第一个单元格中。
因此,如果您想要检索字符串,您只需要知道地址,然后可以从该地址获取以获取长度n,并从地址+ 1开始获取n个字符。