Gforth 将字符串值存储在变量中

7

我正在尝试将一个字符串值存储到一个变量中。为了定义这个变量,我使用:

: define CREATE 0 , ;
define x

我可以轻松地使用以下代码将整数/浮点数值存储到x中:

10 x !

或者

10.0e x f!

我使用@f@来访问它。现在我正在尝试储存一个字符串值:

s" hello world" x !

这样做的问题在于它将两个值推到堆栈上(因为它是一个计数字符串),但是x !只会存储堆栈顶部的项,也就是字符串的长度。这很危险,因为堆栈内容可能已被修改,当引用x时,地址不直接位于长度下方 (坏了!),所以type会失败。那么我的问题是,有没有一种方法可以将两个值(地址和长度)都存储到x中?或者是否有不同的数据类型/操作数可以让我实现这一点?
感谢任何帮助。
4个回答

5
很多用于使其运行所需的东西与您已拥有的非常相似。
如果您想要在创建的内容中存储两个值,则需要不同版本的 define
: 2define create 0 , 0 , ;

在单词开头添加“2”是一种惯例,表示它与没有“2”的单词相同,但是作用于双单元格物品。

要使用它,您需要编写:

2define 2x
//Write something to 2x
s" Hello world!" 2x 2!
//Retrieve it and print
2x 2@ type

值得注意的是,s"返回的地址不能保证在程序的整个运行期间都有效,并且可能会被后续使用s"覆盖。要了解如何创建一个保证持久的字符串变量,请查看此答案https://dev59.com/L17Va4cB1Zd3GeqPNM-l#8748192(有点冗长,但其中有一个名为string的单词定义可能很有启发性)。

2
不要被“!”卡住。这样更有效率...
: 2x S" Hello World!" ;

此句话的意思是:“此外,对于浮点数来说,define不是安全的,可能会出现问题。” 保留html标签,不做解释。
   : define CREATE 0 f, does> f@ ;
 \   3.1459e0 define pi
 \   pi f. 3.1459 ok

我不相信这是在变量中定义字符串。这只是创建一个单词,将相同的内存地址和大小放置在堆栈上。 - Evan Carroll

0
Gforth有一个名为$! ( c-addr u addr -- )的单词,专门用于此目的。给定一个字符串和一个地址,它将字符串复制到新分配的空间中,并将字符串存储在该地址处。如果该地址已经存储了一个字符串,则该字符串将被释放。
因此:
define x
s" hello world" x $!

x $@ type  \ hello world

你还可以使用带有计数字符串和单词的固定缓冲区,例如PLACE和+PLACE,其具有与$!相同的堆栈图片。 与上述内容等效(尽管有字符限制):
256 buffer: x
s" hello world" x place

x count type  \ hello world

s" !" x +place
x count type  \ hello world!

-1
你不能将一个字符串存储在Forth语言中的变量中。 VARIABLE最多只能容纳2、4或8个字符长度的字符串,具体取决于Forth语言的设置。 你必须将S"字符串的每个字符都存储起来,因为该字符串是易变的,稍后通过指针访问时可能会发现内容已经改变。 如果你想要存储一个字符串,你需要一个缓冲区。缓冲区的长度至少要比字符串长(显而易见!),并且字符串的长度必须与之一起存储,以满足字符串的正常含义。 除了分配一个正确大小的缓冲区之外,你还必须执行以下操作。
1024 CONSTANT SIZE \ Pray this is enough
CREATE BUFFER SIZE ALLOT
"AAP" BUFFER $! 

引用的字符串是2012标准,留下(地址,长度)。$!留作练习。^H^H^H^H^H^H
: $! ( cs s -- ) 2DUP ! CELL+ SWAP CMOVE ; 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接