Dan*_*uko 3 arrays common-lisp pass-by-reference multidimensional-array pass-by-pointer
让我们假设我有一个数组 - 我将调用*my-array*- 看起来像这样:
#2A((1 2 3)
(4 5 6)
(7 8 9))
Run Code Online (Sandbox Code Playgroud)
我希望在子阵列上应用一些函数f
#2A((5 6)
(8 9))
Run Code Online (Sandbox Code Playgroud)
我很乐意写作
(f (subarray *my-array* '(1 2) '(1 2))
Run Code Online (Sandbox Code Playgroud)
这里subarray需要作为参数:
我正在寻找一些方法来通过f 引用(或通过指针?)而不是通过值将子数组作为参数传递给函数.
(解决这个问题的愚蠢方法是编写一个函数,在这个特定的情况下创建一个2*2数组并循环i和j复制原始数组中的值.但是,如果你处理相对较大的数组,这个会很贵.)
我发现存在一个cl-slice包但我不知道它是通过引用复制值还是访问数据.
Common Lisp有偏移数组,这正是你所要求的(参见array-displacement&c).
但是,在您的情况下,替换数组没有帮助,因为:
多维数组以行主顺序存储它们的组件; 也就是说,内部多维数组存储为一维数组,多维索引集按字典顺序排列,最后一个索引变化最快.
这意味着您的子数组不是主数组的连续部分,因此,您无法创建替换它的另一个数组.
PS.如果你无法弄清楚cl-slice是如何工作的,你可以用它time来查看它使用了多少内存并从中做出推断.
PPS.事实上,鞭打你想要的东西并不是很难:
(defmacro slice (array &rest ranges)
"Return an accessor into ARRAY randing in RANGES."
(let ((args (loop for r in ranges collect (gensym "SLICE-ARG-")))
(arr (gensym "SLICE-ARRAY-")))
`(let ((,arr ,array))
(lambda ,args
(aref ,arr
,@(loop for arg in args and (lo hi) in ranges
for range = (- hi lo)
collect
`(progn
(unless (<= 0 ,arg ,range)
(error "~S is out of range [0;~S]" ,arg ,range))
(+ ,lo ,arg))))))))
(defparameter *my-array*
#2A((1 2 3)
(4 5 6)
(7 8 9)))
(defparameter f (slice *my-array* (1 2) (1 2)))
(loop for i from 0 to 1 do
(loop for j from 0 to 1 do
(format t " ~S" (funcall f i j)))
(terpri))
5 6
8 9
Run Code Online (Sandbox Code Playgroud)