如何在Forth中创建数组?

时间:2019-01-09 10:48:38

标签: forth

我知道,这个问题过去经常被问到,也许这些信息是在以前的Stack Overflow帖子中给出的。但是学习Forth是一项非常复杂的任务,重复学习有助于理解级联编程语言相对于C等替代语言的优势。

我从Forth教程中学到的是,Forth不提供用于创建2D数组的命令,但是用户必须从程序中从头开始实现一切。我发现在Forth中占用内存有两个选择。首先创建一个新词:

: namelist s” hello” s” world” ;

其次是CREATE语句:

create temperature 10 allot
temperature 10 cells dump

到目前为止一切都很好;我们创建了一个由10个单元格组成的数组,其中可以存储整数变量。但是,如果我需要保存浮点数是什么?我必须始终将float转换为int还是可以将它们保存到普通单元格中?

另一个未解决的问题是如何在数组中存储字符串值。据我所知,一个字符串包含一个指针和一个大小。因此,从理论上讲,我只能在5个单元格中存储5个字符串,此外,我还需要在其他地方保存字符串本身的内存。那没有多大意义。

是否有一些更高的抽象可用于将值存储在可用于编写易于阅读的程序的数组中?我的意思是,如果每个程序员都使用自己的Forth方法将某些内容存储在内存中,那么其他程序员会发现很难读取代码。

3 个答案:

答案 0 :(得分:4)

create创建一个单词,该单词返回字典(数据空间)中缓冲区的地址;最初的长度为零,因此您必须立即为其保留所需的空间。

allot保留以地址单位(通常为字节)度量的空间,因此您必须以字节为单位计算所需的大小。

例如:

create a 10 cells allot
create b 10 floats allot
它只是缓冲区,您仍然需要处理指针算法以获取或设置项目,例如:
0.35e  2 floats b +  f! \ store the float number into third item (0-based indexing)

在字典中创建浮点数组的单词示例:

: create-floats-array ( length "name" -- ) create floats allot does> swap 1- floats + ;

10 create-floats-array c

0.35e  3 c f! \ store the float number into third item (1-based indexing)
3 c f@ f. \ print float number form third item

如果需要许多数组和许多字符串,则最好使用适当的库。 例如,请参见Cell array module中的Dynamic text string moduleForth Foundation Library

答案 1 :(得分:3)

元素的广义2darray。将元素大小作为参数

\ size is the per element multiplier
\ n size * is the per_row factor
\ m n size * * is the total space required

: 2darray  \ create>  m n size -- ; does> mix nix -- a
\  size is the number of bytes for one element
\  
  create  2dup * ,      \ multiplier to apply to m index 
          dup ,         \ multiplier to apply to n index
          * * allot     \ calculate total bytes and allot them
  does>  \ mix nix a 
    >r r@ cell+ @ *     \ offset from n index  
       swap r@ @ * +    \ offset with m index
   r> + 2 cells+        \ 2 cells offset for the 'admin' cells
;

示例

50 40 /float 2darray 50x40floats
50 40 2 cells 2darray 50x40stringpairs

20 constant /record
10 200 /record 2darray 2000records

答案 2 :(得分:0)

您对字符串感到困惑。字符串刚刚进入内存,并且为该字符串分配了该地址的内存,并且该内存一直存在(除非您进行更改)。

因此,如果您想在分配的内存块中存储5个(c-addr u)字符串(称其为数组有点麻烦),则只需将c-addr存储在单元格 n中和单元格 n + 1 中的长度u。

如果您担心10个单元格会占用很大的空间(这实际上没什么可担心的),而只想使用5个单元格,则可以使用C"之类的字词将字符串存储为计数的字符串-计数的字符串将长度存储在第一个字节中,随后的每个字节都是一个字符。

此外,您还可以使用单词dp(逗号)将事物存储在当前,的字典中。