(defun test (lst / x)
(setq x 1)
(foreach x lst (setq x 2))
x
)
(test '(1 2 3)) =>1
这个代码中的foreach部分,实际上是个子函数,这个子函数返回的最后值是2, 到主函数中并没有将其赋给x变量,而子函数中的x是局部变量,这也是通行的做法, 所以主函数中的值并没有被改变,这个是比较好理解的,如果改为mapcar、vl-remove-if等结合lambda临时函数也是一样的效果
(defun test (lst / x)
(setq x 1)
(mapcar'(lambda(x)(setq x 2))lst)
x
)
(defun test (lst / x)
(setq x 1)
(vl-remove-if-not'(lambda(x)(and(= x 2)(setq x 2)))lst)
x
)
关于a b值对换的那个函数个人认为,这样写也是可以的, 给函数传入的是 '(3 4) 返回的是'(4 3) 让函数有个返回值(函数执行还是要通过返回值来体现结果)这样也算是达到目的了
(setq a 3 b 4)
(defun swap (x y / temp)
(setq temp x x y y temp)
(list x y)
)
(swap a b)
用函数返回结果来表达 (setq x 3 y 4) (swap x y) 的返回值也是交换了的,当然如果要让x y变量的值改变,即!x !y的值也改变,必须重新赋值
(setq fhz(swap x y)) (setq x(car fhz)) (setq y(cadr fhz))
如果不用函数来实现,也可以直接用赋值语句也可以实现目的 (setq a 3 b 4) (setq temp a a b b temp)
函数定义过程列出的参数均为形参(形式意义上的参数,没有值)
在调用有参函数时所用的的参数为“实际参数”。它包含了实实在在的数据,会被函数内部的代码使用。与形参一一对应,否则会发生错误
一般情况下,实参传递值给形参,在被调用的函数内部不管对形参怎么修改,实参不会改变
但特殊情况下,修改形参会导致实参被修改,如果实参不是以值的形式传递给形参而是以地址方式传递的话,比如
(vla-GetBoundingBox obj 'a 'b)会修改a和b,这里参数传递方式是明确了按地址传递的,此处没有陷阱。
另ssdel和ssadd会对实参进行修改,但传递参数的时候并没有向上边一样明确指定按址传递(ssdel e ss)(ssadd e ss)都会把返回值修改到ss变量,此处可以认为是有益的陷阱,因为可以省去一个setq而达到修改变量为函数返回值的目的
一般说传址的陷阱是指,传参过程并没有明确哪个参数需要按址传递,但函数返回值的同时,会对某些实参进行修改,修改的结果还不一定是所调用的函数的返回值,可能只是那个函数执行过程的一些过程数据,所以对于不太熟悉的函数需要多测试它,才可能发现它的问题,使用过程中避免它