【问题标题】:If there a pointers in lisp programming?lisp编程中是否有指针?
【发布时间】:2021-05-01 17:49:09
【问题描述】:

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

【问题讨论】:

  • 不,Lisp 没有指针。许多 Lisp 实现都将它们作为扩展,因此一些内置函数可以用 Lisp 编写并与底层 C 实现接口。
  • 如果 lisp 中没有指针,那么 lisp 中是否有可以与指针具有相同概念的命令?
  • 我的意思是就像 Solidity。 Solidity 没有 switch case,但你可以做 switch-case 赢得 if-else 的一种形式。
  • Lisp 值通常以指针的形式实现(除了像 fixnums 这样的立即值)。但是没有什么类似于您在 C 等语言中找到的通用指针。它们只是指向整个对象的指针,没有什么比指向特定数组元素的指针更相似。
  • 当然,你可以做更高级别的(cons array index)。事实上,这就是 Lisp Machine C 实现 C 指针的方式。但它并没有概括——你不能使用相同的符号来获取指向 cons 中特定单元格的指针。

标签: pointers lisp


【解决方案1】:

Lisp 没有实际的指针。但是根据fundamental theorem of software engineering,我们可以通过添加一个间接级别来模拟它们。我们可以使用某种容器,例如 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 中的一些指针安全问题;他们可以检查偏移量是否在范围内,防止增加不指向数组元素的指针等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-20
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 2011-06-03
    • 1970-01-01
    相关资源
    最近更新 更多