首页 > 解决方案 > lisp编程中是否有指针?

问题描述

我没有具体的示例代码或任何东西。我只想知道lisp中是否有指针。如果有请分享一个简单的例子

标签: pointerslisp

解决方案


Lisp 没有实际的指针。但是根据软件工程的基本定理,我们可以通过添加一个间接级别来模拟它们。我们可以使用某种容器,例如 cons cell 或 defstruct。

(defstruct pointer
    array
    offset)
(defun pointer-deref (ptr)
  (aref (pointer-array ptr) (pointer-offset ptr)))
(defun set-pointer-deref (ptr value)
  (setf (aref (pointer-array ptr) (pointer-offset ptr)) value))
(defsetf pointer-deref set-pointer-deref)

(defvar my-array (vector 1 2 3 4 5 6 7 8 9 10))
(defvar my-ptr (make-pointer :array my-array :offset 3))
(print (pointer-deref my-ptr)) ; prints 4
(setf (pointer-deref my-ptr) 20)
(print my-array) ; prints #(1 2 3 20 5 6 7 8 9 10)
(incf (pointer-offset my-ptr))
(print (pointer-defer my-ptr)) ; prints 5
(defvar my-array-2 (vector 15 30 40))
(setf (pointer-array my-ptr) my-array-2 (pointer-offset my-ptr) 0)
(print (pointer-deref my-ptr)) ; prints 15

上面的代码大致类似于这段 C 代码:

int my_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *my_ptr = &my_array[3];
printf("%d\n", *my_ptr);
*my_ptr = 20;
for (int i = 0; i < 10; i++) {
  printf("%d ", my_array[i]);
}
my_ptr++;
printf("%d\n", *my_ptr);
int my_array2[] = {15, 30, 40};
my_ptr = &my_array2[0];
printf("%d\n", *my_ptr);

为了与 Lisp 的动态类型保持一致,这些指针可以指向任何类型的数据,您不必声明类型。另一方面,这个实现只支持指向数组元素的指针,而 C 指针也可以指向变量和结构成员。更复杂的实现可以使用 CLOS 来定义不同类的指针,并使用通用函数来允许您一致地使用它们。这也可以解决 C 中的一些指针安全问题;他们可以检查偏移量是否在范围内,防止增加不指向数组元素的指针等。


推荐阅读