明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4293|回复: 12

[【不死猫】] [原创]发现Lisp类指针操作,可以传递地址直接修改变量的值

[复制链接]
发表于 2014-9-10 11:54 | 显示全部楼层 |阅读模式
本帖最后由 不死猫 于 2014-9-10 13:08 编辑

在第二个函数中修改当前函数局部变量:
  1. (defun changeSYM (x)
  2.   (set x 123)
  3. )
  4. (defun c:qq(/ a)
  5.   (setq a 1)
  6.   (print (list "初始化a值" a))
  7.   (changeSYM 'a)
  8.   (print (list "通过地址赋值后" a))
  9.   (princ)
  10. )
  11. (c:qq)
执行结果:
("初始化a值" 1)
("通过地址赋值后" 123)

=====================
通过函数交换局部变量的值:(我通过两个不同的方法来测试变量的改变)
  1. ;地址传递可以改变变量的值
  2. (defun x<->y (x y / z)
  3.   (setq z (eval x))
  4.   (set x (eval y))
  5.   (set y z)
  6. )
  7. ;值传递无法改变变量的值(这段不用说必然失败的)
  8. (defun x-y(x y / z)
  9.   (setq z x)
  10.   (setq x y)
  11.   (setq y z)
  12. )
  13. (defun c:tt(/ b c)
  14.   (setq b 1 c 2)
  15.   (print (list "初始值" b c))
  16.   (x-y b c)
  17.   (print (list "第一次交换" b c))
  18.   (x<->y 'b 'c)
  19.   (print (list "第二次交换" b c))
  20.   (princ)
  21. )
  22. (setq b nil c nil x nil y nil z nil)
  23. (c:tt)
  24. (list "局部变量自动释放" b c x y z)
执行结果:

("初始值" 1 2)
("第一次交换" 1 2)
("第二次交换" 2 1)
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2015-9-14 17:42 | 显示全部楼层
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2014-9-10 12:27 | 显示全部楼层
本帖最后由 不死猫 于 2014-9-10 12:32 编辑

以前我们想要交换数据的话要这样写
(setq a ...)
(setq a (函数名 a))
现在通过地址修改值的方式
只需写
(函数名 'a)
即可达到对变量a修改的目的.

当我们有很多变量传过去要修改的时候,比如坐标变换.
以前这样写
(setq get (函数名 x y z))
(setq x (car get) y (cadr get) z (last get))
如果这样处理
(函数名 'x 'y 'z)
就不用返回list再单独提取数据了.
发表于 2014-9-10 12:28 | 显示全部楼层
猫老师节日快乐.....

什么情况要这样做....写的程序都很简单...这个好厉害的样子....

点评

对于多参数转换数据的函数,比较容易进行数据的处理.以前都是返回一个表再单独提取,或者使用全局变量.  发表于 2014-9-10 12:34
发表于 2014-9-10 12:38 | 显示全部楼层
不死猫 发表于 2014-9-10 12:27
以前我们想要交换数据的话要这样写
(setq a ...)
(setq a (函数名 a))

有点明白了...这样方便......要试试...
 楼主| 发表于 2014-9-10 12:44 | 显示全部楼层
本帖最后由 不死猫 于 2014-9-10 12:46 编辑

其实我们在vla-getboundingbox 函数中已经看到了眉目
(vla-getboundingbox object 'pta 'ptb)
为了让我们得到两个坐标点,就通过地址传递的方法返回来两个坐标点
否则我们还要再写一句拆分返回值.
发表于 2014-9-10 12:45 | 显示全部楼层
这次不太赞同你了,set有指针的意思,但仍旧不能改变局部变量,以你的代码来测试:
  1. 命令: (setq a 111)
  2. 111
  3. 命令: qq
  4. ("初始化a值" 1)
  5. ("通过地址赋值后" 123)
  6. 命令:
  7. 命令: !a
  8. 111
可以看出,先前赋值的变量a,在c:qq中被作为局部变量,虽然经过变换,但退出后仍旧回到原值。
你这里的问题出在,你的变换都是在c:qq一段程序中,而a也是在这个程序中被作为局部变量的,这就是自身检测自身,所以是不成立的。
这里应该是有类似闭包的东西,在程序运行时,上层的环境是封闭起来的,局部变量在程序环境中是全局变量,所以可以变化,但并不影响上层的封闭环境。
有调整局部变量嫌疑的还有选择集函数,但我通过努力,仍旧无法真正调整。

点评

此全局a与局部a在内存中不是同一个地址,相当于两个完全不同的变量:)这样测试是不对的啦.  发表于 2014-9-10 12:56
 楼主| 发表于 2014-9-10 12:50 | 显示全部楼层
本帖最后由 不死猫 于 2014-9-10 12:59 编辑
ll_j 发表于 2014-9-10 12:45
这次不太赞同你了,set有指针的意思,但仍旧不能改变局部变量,以你的代码来测试:可以看出,先前赋值的变量 ...


注意你的全局变量(setq a 111)是不会进入我程序中的.当然还是111
用全局变量来测试这个传递,本身就是有点误解了.
你的a 与我函数中局部变量 a 被lisp分配为不同的内存地址. 局部变量都是临时开辟的,不会影响全局变量.
通过你用全局变量测试,也从侧面证明了这种传递的地址是调用函数中的a的地址,不会与全局变量冲突,是一个很好的测试证明理论正确的例子:)
发表于 2014-9-10 12:58 | 显示全部楼层
不死猫 发表于 2014-9-10 12:50
注意你的全局变量(setq a 111)是不会进入我程序中的.当然还是111
用全局变量来测试这个传递,本身就是有 ...

x-y通过z进行交换是最基本的交换,set函数有指针传递的意思。我想你是被绕住了,再想想
 楼主| 发表于 2014-9-10 12:58 | 显示全部楼层
如果你想改变全局变量请这样写:
命令: (setq a 111)
111
命令: (changeSYM 'a)
123
命令: !a
123
 楼主| 发表于 2014-9-10 13:02 | 显示全部楼层
本帖最后由 不死猫 于 2014-9-10 13:09 编辑

x-y 是我说明仅仅通过值传递是不能改变当前函数变量的值,通过x<->y地址传递才可以.
我没有写清楚注释 sorry 已补充注释.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-2 06:00 , Processed in 0.426916 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表