找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2531|回复: 7

[日积月累]:对变量、函数、局部、全局等概念的肤浅认识

[复制链接]
发表于 2006-8-28 22:05:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
对变量、函数、局部、全局等概念的肤浅认识
qjchen
前段时间论坛有过一个函数变量的讨论,让我感触颇深
最近又编了一个很长很长的代码,
因此对变量,函数,局部,全局等概念觉得有必要比较认真的反思一下

于是,做了如下的一些测试,得到了一些体会
由于我是业余编程,本来就是靠蛮劲在编程的,二来Lisp这种语言的函数和变量是同一概念,搞得自己也比较模糊
因此得到的这些看法很肤浅,各位可能早就思考过了,见笑见笑
各位可以先看代码,估算一下结果,假如各位估算全对的话,就完全不用看了,都是很简单的东西

1)当一个函数没有终结的时候,这个函数内的局部变量可以被其他子程序所调用。
这个问题的范例代码是:

  1. (defun c:test (/ a b)
  2.   (setq a 1
  3.             b 2
  4.   )
  5.   (fun 0 1)
  6. )

  7. (defun fun (x y)
  8.   (+ (+ x a) (+ y b))
  9. )

我原来一直以为中途跑出test去fun中,局部变量会丢失,现在看起来是错误的。
只要这个程序没有终结,里面的各种变量都存在内存空间,只有程序终结了,变量才被清空。

2)在defun里面的定义为局部变量的defun函数不能被其他函数调用
这个问题的范例代码是:

  1. (defun c:test ()
  2.   (setq x (ee 2))
  3. )

  4. (defun fun1 ()
  5.   (defun ee (x)
  6.     (+ x 6)
  7.   )
  8. )

可以看出是没有结果的,以前不大明白为什么要把一段那么长的defun写在别的defun里面,
现在觉得可能有些作用,起码这些函数不会和别的变量或者函数同名,而且可能也起到节省内存空间的作用。
这个可以通过在命令行输入!fun1和!ee来认知

3)其实Lisp里面的函数和变量几乎都是一样的,可能这就是Lisp的本质吧,一种表结构的语言

  1. (defun c:test (/ x)
  2.   (setq x (fun1 5))
  3. (princ "\n               x = ") (princ x);Erase_DV
  4. (getstring "\nPress Enter to continue...");Erase_DV
  5.   (setq xx (eee 6))
  6. (princ "\n              xx = ") (princ xx);Erase_DV
  7. (getstring "\nPress Enter to continue...");Erase_DV
  8. )

  9. (defun fun1 (y)
  10.   (defun eee (x)
  11.     (+ x 6)
  12.   )
  13.   (eee y)
  14. )

可以看出,是都有结果的,所以呢,刚才(2)中提到的defun中的defun不能被其他程序调用的情况要加适用条件了
这个适用条件就是“局部变量”
在这个例子中,假如先调用eee的话是不行的,但是先调用了fun1之后,eee由于不是fun1的局部变量,
就存在了内存空间了,没有被清除

4)传递变量在函数终结时被清空

  1. ;;---------------------------------
  2. (defun c:test ()
  3.   (setq a 5
  4.         b 6
  5.   )
  6.   (setq c (fun2 1 2))
  7. (princ "\n               a = ") (princ a);Erase_DV
  8. (princ "\n               b = ") (princ b);Erase_DV
  9. (getstring "\nPress Enter to continue...");Erase_DV
  10.   
  11. )
  12. (defun fun2 (a b)
  13. (princ "\n               a = ") (princ a);Erase_DV
  14. (princ "\n               b = ") (princ b);Erase_DV
  15. (getstring "\nPress Enter to continue...");Erase_DV
  16.   (list (+ a 1) (+ b 2))
  17. )

可以看出fun2中的a b在fun2结束之后就不复存在了,所以传递变量只是临时存在这个引用函数中,与其他变量同名也无妨


5)总结
在写了上面一堆东西之后,好像突然间想通了,又好像白写了,这个应该就是认知的曲折过程吧
只要掌握了---Lisp中变量和函数是等同的,局部变量(函数)在函数结束后才被清空,全局变量则在关闭图形时清空,
传递变量不影响同名变量 这几个原则,理解起来就轻松一些了。
一时间的乱写,不对之处请指正。
我也会继续做测试。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1个

财富等级: 恭喜发财

发表于 2006-8-29 12:33:54 | 显示全部楼层
关键概念的梳理比一个有用的程式重要百倍,多谢楼主分享。菜鸟期待着您的继续测试的精彩篇章。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-8-29 12:51:24 | 显示全部楼层
怎么冒出个传递变量?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-8-29 15:02:21 | 显示全部楼层
谢谢刀兄,这个就是我业余的很的地方了,连名称都是这么的业余,脸红。
查了一下fortran中的,defun fun(a b / c d)中的a b 好像是叫做虚参,主要是做数据传递的
不知道Lisp里面怎么称呼,是叫全局变量还是局部变量好呢。还是直接叫它参数好?
谢谢啊谢谢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6530个

财富等级: 富甲天下

发表于 2006-8-29 19:43:01 | 显示全部楼层
Lisp中就称“参数”,也有称作“变元”的。

看一个例子:

  1. (setq X '((1 2) (3 5)))          ;设置变量x
  2. (mapcar                           ;遍历,对象为上面设定的X
  3.    '(lambda(x)                    ;以x为参数1
  4.       (mapcar                     ;对参数1x遍历,对象为X的表元素
  5.         '(lambda(x)               ;以x为参数2
  6.            (+ 1 x)                   ;对参数2运算
  7.         )                               ;end lambda
  8.        x                               ;参数1
  9.      )                                  ;end mapcar
  10.     )                                   ;end lambda
  11.   x                                    ;遍历的对象:X
  12. )                                       ;end mapcar

返回:'((2 3) (4 6))
Lisp中大小写是不分的,上面的X只是为了看明白些,以上设置的值、两级使用的参数都是x,运行仍然正常,说明参数x只是一个“临时符号”,使用后会自动立即清除。

最后检查x的值: !x
返回:'((1 2) (3 5))
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-11-25 13:08:34 | 显示全部楼层
2楼:
关键概念的梳理比一个有用的程式重要百倍,多谢楼主分享。菜鸟期待着您的继续测试的精彩篇章。

但是光是概念的抽象的理论也不行啊,还得具体的形象地,所以需要一些程序例子才能更加理解透彻。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-11-25 13:46:17 | 显示全部楼层
(defun c:test (/ a b)
  (setq a 1
            b 2
  )
  (fun 0 1)
  (+ a b)
)
(defun fun (x y / a b)
  (setq a 3 b 4)
  (+ (+ x a) (+ y b))
)
在fun里a   b就是3   4      在test里a   b就是1   2
意思就是在fun里定义了a   b,则a   b就用fun里面的值,没定义就是test里的变量
有点意思
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-11-27 16:42:39 | 显示全部楼层
以前学的LISP语言不用都已经忘记了,现在我也在慢慢回忆中
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-7 15:52 , Processed in 0.436591 second(s), 45 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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