马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
对变量、函数、局部、全局等概念的肤浅认识
qjchen
前段时间论坛有过一个函数变量的讨论,让我感触颇深
最近又编了一个很长很长的代码,
因此对变量,函数,局部,全局等概念觉得有必要比较认真的反思一下
于是,做了如下的一些测试,得到了一些体会
由于我是业余编程,本来就是靠蛮劲在编程的,二来Lisp这种语言的函数和变量是同一概念,搞得自己也比较模糊
因此得到的这些看法很肤浅,各位可能早就思考过了,见笑见笑
各位可以先看代码,估算一下结果,假如各位估算全对的话,就完全不用看了,都是很简单的东西
1)当一个函数没有终结的时候,这个函数内的局部变量可以被其他子程序所调用。
这个问题的范例代码是:

- (defun c:test (/ a b)
- (setq a 1
- b 2
- )
- (fun 0 1)
- )
- (defun fun (x y)
- (+ (+ x a) (+ y b))
- )
我原来一直以为中途跑出test去fun中,局部变量会丢失,现在看起来是错误的。
只要这个程序没有终结,里面的各种变量都存在内存空间,只有程序终结了,变量才被清空。
2)在defun里面的定义为局部变量的defun函数不能被其他函数调用
这个问题的范例代码是:

- (defun c:test ()
- (setq x (ee 2))
- )
- (defun fun1 ()
- (defun ee (x)
- (+ x 6)
- )
- )
可以看出是没有结果的,以前不大明白为什么要把一段那么长的defun写在别的defun里面,
现在觉得可能有些作用,起码这些函数不会和别的变量或者函数同名,而且可能也起到节省内存空间的作用。
这个可以通过在命令行输入!fun1和!ee来认知
3)其实Lisp里面的函数和变量几乎都是一样的,可能这就是Lisp的本质吧,一种表结构的语言

- (defun c:test (/ x)
- (setq x (fun1 5))
- (princ "\n x = ") (princ x);Erase_DV
- (getstring "\nPress Enter to continue...");Erase_DV
- (setq xx (eee 6))
- (princ "\n xx = ") (princ xx);Erase_DV
- (getstring "\nPress Enter to continue...");Erase_DV
- )
- (defun fun1 (y)
- (defun eee (x)
- (+ x 6)
- )
- (eee y)
- )
可以看出,是都有结果的,所以呢,刚才(2)中提到的defun中的defun不能被其他程序调用的情况要加适用条件了
这个适用条件就是“局部变量”
在这个例子中,假如先调用eee的话是不行的,但是先调用了fun1之后,eee由于不是fun1的局部变量,
就存在了内存空间了,没有被清除
4)传递变量在函数终结时被清空

- ;;---------------------------------
- (defun c:test ()
- (setq a 5
- b 6
- )
- (setq c (fun2 1 2))
- (princ "\n a = ") (princ a);Erase_DV
- (princ "\n b = ") (princ b);Erase_DV
- (getstring "\nPress Enter to continue...");Erase_DV
-
- )
- (defun fun2 (a b)
- (princ "\n a = ") (princ a);Erase_DV
- (princ "\n b = ") (princ b);Erase_DV
- (getstring "\nPress Enter to continue...");Erase_DV
- (list (+ a 1) (+ b 2))
- )
可以看出fun2中的a b在fun2结束之后就不复存在了,所以传递变量只是临时存在这个引用函数中,与其他变量同名也无妨
5)总结
在写了上面一堆东西之后,好像突然间想通了,又好像白写了,这个应该就是认知的曲折过程吧
只要掌握了---Lisp中变量和函数是等同的,局部变量(函数)在函数结束后才被清空,全局变量则在关闭图形时清空,
传递变量不影响同名变量 这几个原则,理解起来就轻松一些了。
一时间的乱写,不对之处请指正。
我也会继续做测试。 |