我正在研究一种简单的 lisp 风格的预处理器语言。
在 API 中,我希望用户能够将任何维度和大小的数组传递到可以使用该语言进行操作的预处理器。
目前我有一个类型枚举;
typedef enum LISP_TYPE
{
LT_UINT,
LT_FLOAT,
LT_ARRAY
...,
...
} _LISP_TYPE;
我无法找到一种有效且易于使用的方法来存储数组并访问它们。
我还有另一种专门用于数组的结构;
typedef struct _lisp_array
{
LISP_TYPE type;
unsigned int length;
void* data;
} lisp_array;
当预处理器看到类型为 LT_ARRAY 的列表原子时,它会将其 void*
(lisp 术语中的 cdr)转换为上述结构。我遇到问题的地方是弄清楚如何访问多维数组。我曾想过计算一个步长值来遍历数组,但是我可以保证所有传递的数组都会被连续分配吗?
任何帮助表示赞赏。
I am working on a simple lisp-style pre-processor language.
In the API i want users to be able to pass arrays of any dimension and size to the pre-processor which can be manipulated using the language.
Currently i have an enum of types;
typedef enum LISP_TYPE
{
LT_UINT,
LT_FLOAT,
LT_ARRAY
...,
...
} _LISP_TYPE;
I am having trouble finding an efficient and easy to use method of storing arrays and also accessing them.
There is another structure i use specifically for arrays;
typedef struct _lisp_array
{
LISP_TYPE type;
unsigned int length;
void* data;
} lisp_array;
When the pre-processor See's a list atom with type LT_ARRAY, it will convert its void*
(cdr in lisp terms) to the above structure. Where i am having problems is figuring out how to access multi-dimensional arrays. I have thought of calculating a step value to traverse the array but can i guarantee that all arrays passed will be contiguously allocated?
Any help is appreciated.
发布评论
评论(3)
C 内置(单维和多维)数组保证以行优先模式存储在内存的一个连续区域中。然而,这可能无法回答您的问题。 _lisp_array::data 成员所指向的数据结构的预期布局是什么?
C built-in (singe and multi-dimensional) arrays are guaranteed to be stored in one contiguous region of memory in row-major mode. This may not answer your question, however. What is the expected layout of the data structure pointed to by _lisp_array::data member?
由于您正在编写解释器,因此由您决定表示形式并使数组连续 - 也就是说,如果您需要它是连续的。如果使其连续,则可以通过以下方式访问元素(假设从零开始的索引 a、b、c... 和维度大小 sa、sb、sc...):
还有其他表示数组的方法,例如当然 - 您可以使用数组指针数组等。每个都有其自己的优点和缺点;在没有任何用例细节的情况下,如果数组的边界是固定的,并且数组预计不会是稀疏的,那么连续缓冲区通常是一种合理的方法。
Since you're writing the interpreter, it's up to you to decide on the representation and make the array contiguous - that is, if you need it to be contiguous. If you make it contiguous, you can access elements by, for example (assuming zero-based indices a, b, c... and dimension size sa, sb, sc...):
There are other ways of representing arrays, of course - you could use arrays-of-pointers-to-arrays, etc. Each has its own advantages and disadvantages; without any specifics on the use case, if the bounds of the array are fixed, and the array is not expected to be sparse, then a contiguous buffer is usually a reasonable approach.
这实际上取决于你想让它有多像 lisp。 Lisp 并没有你所想到的多维数组的严格定义——所有的东西要么是一个原子,要么是一个列表。它最接近的东西是数组的数组:
但请注意,子数组的长度不同。但本质上它们不一定是口齿不清的,而且我不认为有办法强制解决这个问题......
如果你需要严格的“矩形”数组,这显然是行不通的,但如果你有回旋余地,这就是我实现它的方式 - 这是一个漂亮、干净的结构(查看 维基百科页面 了解更多详细信息)。
干杯!
It would depend on how lisp-like you wanted to make it, really. Lisp doesn't have the strict definition of multi-dimensional arrays you're thinking of - everything is either an atom or a list. The closest thing it would have is an array of arrays:
Note, though, that the sub-arrays aren't the same length. But it's inherently lispy that they don't have to be, and I don't think there's a way to force the issue...
If you need strictly "rectangular" arrays this won't work, obviously, but if you've got wiggle-room, this is how I'd implement it - it's a nice, clean structure (check out the Wikipedia page for more details).
Cheers!