乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 22|回复: 9

[编程交流] 子定义和局部变量B

[复制链接]

6

主题

25

帖子

19

银币

初来乍到

Rank: 1

铜币
30
发表于 2022-7-5 17:39:36 | 显示全部楼层 |阅读模式
我已经创建了一个包含DCL文件的lisp&我希望将其用作任何未来将受益于切换界面的lisp的模板。
它起作用了,有点。。
这真的是两个问题合一。
1) 主功能内部或外部的子定义?
(defun getvalues()和/或(defun create_dialog()应该在里面吗?还是在外面?
2) 在多定义LISP中定位变量。
每个defun应该定位哪些变量?
 
我的代码:
  1. (defun c:main ( / an ans1 ans2 ans3 ans4 dcl_id fn fname)
  2. (vl-load-com)
  3. (create_dialog)
  4. (setq dcl_id (load_dialog fname))
  5.    (if (not (new_dialog "temp" dcl_id))
  6.        (exit)
  7.        (progn        
  8.        (action_tile "accept" "(getValues)")
  9.        (action_tile "cancel" "(done_dialog 0)")
  10.        (setq an (start_dialog))
  11.         )                                                 ;end progn
  12.      )                                                    ;end if
  13. (unload_dialog dcl_id)
  14. (cond ((= an 1)
  15.       (alert (strcat "Layer to 0 is: < " ans1 " > \nLTscale to 1 is: < " ans2 " > \nColour to Bylayer is: < " ans3 " > \nLType to Bylayer is: < " ans4 " >"))
  16.        )
  17. )
  18. (vl-file-delete fname)
  19. (princ)
  20. );defun c:test
  21. (defun getvalues ()
  22. (setq ans1 (get_tile "t1")
  23.       ans2 (get_tile "t2")
  24.       ans3 (get_tile "t3")
  25.       ans4 (get_tile "t4"))
  26. (done_dialog 1)
  27. ); defun getvalues
  28. (defun create_dialog ()
  29. (setq fname (vl-filename-mktemp "dcl.dcl"))
  30. (setq fn (open fname "w"))
  31. (write-line
  32. "temp :dialog { label = "Set Sub-Entities to:" ;
  33.     :toggle  {
  34.        label          = "Layer to 0" ;
  35.        alignment   = centered;
  36.        key            = t1;
  37.        value          =  1;
  38.          }
  39.     :toggle  {
  40.        label          = "LTscale to 1" ;
  41.        alignment   = centered  ;
  42.        key            = t2;
  43.        value          =  1;
  44.          }
  45.     :toggle  {
  46.        label          = "Colour to Bylayer" ;
  47.        alignment   = centered;
  48.        key            = t3;
  49.        value          =  1;
  50.          }
  51.     :toggle  {
  52.        label          = "LType to Bylayer" ;
  53.        alignment   =  centered;
  54.        key            = t4;
  55.        value          =  1;
  56.          }         
  57.    ok_cancel;
  58. } " fn)
  59. (close fn)
  60. );defun create_dialog
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 17:46:48 | 显示全部楼层
你好,Simon1976,
我只是尝试在我的主函数中添加subdefun,它工作得很好。
通常,子函数(也称为“子函数”)位于主函数之外,因此可以缩短主代码,并且相同的子函数可以轻松地在其他新代码中重用。
还下面是一个示例,如果subdefun位于主函数内,它将如何工作:
  1. (defun C:main ( / args )
  2. (defun subfunction1)
  3. (defun subfunction2)
  4. ; Start the main code:
  5. (if
  6.         (and
  7.                 (stuff)
  8.         );and
  9.         (progn
  10.                 (stuff)
  11.         );progn
  12. );if       
  13. );main defun

下面是一个例子,您会得到错误“无法加载xxx.lsp”
  1. (defun C:main ( / args )
  2. ; Start the main code:
  3. (if
  4.         (and
  5.                 (stuff)
  6.         );and
  7.         (progn
  8.                 (defun subfunction1)
  9.                 (defun subfunction2)
  10.                 (stuff)
  11.         );progn
  12. );if       
  13. );main defun

据我所知,用户输入的变量必须本地化(以及其他与这些变量有联系的人等等),否则当例程结束时,它们不会重置为零。
通常我会尝试在每段代码中本地化所有变量(我不确定这样做是否正确),但我记得取消变量本地化的唯一原因是为了记住用户的输入:
  1. ;Remembers selected choice
  2. ;LM Dynamic Default
  3. (defun C:test ()
  4. (if (not *ans*) (setq *ans* "A4"))
  5. (initget "A0 A1 A2 A3 A4")
  6. (setq *ans* (cond ( (getkword (strcat "\nSelect option [A0/A1/A2/A3/A4] <" *ans* ">: "))) ( *ans* )))
  7. (cond
  8.         ((= *ans* "A0") (princ (strcat "\nFinal choice is " *ans* )))
  9.         ((= *ans* "A1") (princ (strcat "\nFinal choice is " *ans* )))
  10.         ((= *ans* "A2") (princ (strcat "\nFinal choice is " *ans* )))
  11.         ((= *ans* "A3") (princ (strcat "\nFinal choice is " *ans* )))
  12.         ((= *ans* "A4") (princ (strcat "\nFinal choice is " *ans* )))
  13. )
  14. (princ)
  15. );defun
回复

使用道具 举报

63

主题

6297

帖子

6283

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
358
发表于 2022-7-5 17:53:35 | 显示全部楼层
嗨,西蒙,
 
本地化功能被认为是最好的方式,除非你在另一个程序中使用相同的功能,并将其放入你的ACADDOC。lsp文件。
在您的示例中,我建议对函数进行本地化,并确保在调用函数之前将函数放置在程序中,以确保函数已加载,并避免整个程序出现任何故障。
 
祝你好运
 
或者,只要您确定全局变量*ans*持有一个值并且不等于零。
 
  1. (princ (strcat "\nFinal choice is " (car (member *ans* '("A0" "A1" "A2" "A3" "A4")))))
回复

使用道具 举报

6

主题

25

帖子

19

银币

初来乍到

Rank: 1

铜币
30
发表于 2022-7-5 17:59:47 | 显示全部楼层
不幸的是,我认为你们都没有抓住要点(可能解释得很糟糕),我不想要任何全局变量
第一季度:
如果是:
  1. (defun main
  2. code
  3. .......
  4. .......
  5. (defun getvalues); This is [color=darkorange]INSIDE [/color]main
  6. code
  7. ........
  8. ........
  9. );end defun getvalues
  10. );end defun main
  11. OR:
  12. (defun main
  13. code
  14. .......
  15. .......
  16. );end defun main
  17. (defun getvalues); This is [color=darkorange]OUTSIDE[/color] main
  18. code
  19. ........
  20. ........
  21. );end defun getvalues
  22. Q2:
  23. Should main be:
  24. (defun c:main ( / [color=red]an ans1 ans2 ans3 ans4 dcl_id fn fname[/color]); All declared as [color=red]variables[/color]
  25. or
  26. (defun c:main ([color=royalblue]ans1 ans2 ans3 ans4[/color] / [color=red]an dcl_id fn fname[/color]); ans1 - ans4 declared as [color=royalblue]arguements[/color], an dcl_id fn fname declared as [color=red]variables[/color]
  27. And should getvalues be:
  28. (defun getvalues ()
  29. or
  30. (defun getvalues ( [color=royalblue]ans1 ans2 ans3 ans4[/color] / ); all declared as [color=royalblue]arguments
[/颜色]
很抱歉,代码标签按钮似乎对我不起作用&我最终手动将它们放入
回复

使用道具 举报

63

主题

6297

帖子

6283

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
358
发表于 2022-7-5 18:06:23 | 显示全部楼层
西蒙,请修改你的帖子并使用标签代码,看看这个
回复

使用道具 举报

63

主题

6297

帖子

6283

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
358
发表于 2022-7-5 18:13:29 | 显示全部楼层
 
 
Simon上述回复直接发送给Grrr。
 
 
 
这就是我的意思:
 
  1. (defun c:main ( / getvalues)
  2. (defun getvalues (/ a b c)
  3.    (setq a 1
  4.          b 2
  5.          c 3
  6.          )
  7.    (+ a b c)
  8.    )
  9. (alert (itoa (getvalues)))
  10. (princ)
  11. )

 
因此,上述操作应该有效,并在消息框中给出6的总数。
 
以及以下函数getvalues未本地化且位于主函数之外的函数。
 
  1. (defun c:main ( / )
  2. (alert (itoa (getvalues)))
  3. (princ)
  4. )
  5. (defun getvalues (/ a b c)
  6.    (setq a 1
  7.          b 2
  8.          c 3
  9.          )
  10.    (+ a b c)
  11.    )

 
最后一个应该给出一个错误,因为函数SumValues之前没有加载,所以在加载之前调用它。
 
  1. (defun c:main ( / )
  2. (alert (itoa (SumValues)))
  3. (defun SumValues (/ a b c)
  4.    (setq a 1
  5.          b 2
  6.          c 3
  7.          )
  8.    (+ a b c)
  9.    )
  10. (princ)
  11. )

 
错误消息:
回复

使用道具 举报

6

主题

25

帖子

19

银币

初来乍到

Rank: 1

铜币
30
发表于 2022-7-5 18:25:20 | 显示全部楼层
Simon上面的回复是直接发给Grrr的“哦。
 
 
我正在努力理解这一点,非常感谢塔瓦。
回复

使用道具 举报

63

主题

6297

帖子

6283

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
358
发表于 2022-7-5 18:26:34 | 显示全部楼层
非常欢迎你,西蒙。
 
如果你有任何问题,尽管问。
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 18:37:47 | 显示全部楼层
谢谢,塔瓦!
你可以看到,我试图避免使用列表,但这是一个非常古老的例子。
至少在我开始学习LISP时,我曾经用这种方式操作设置好的引号。
我知道这是一种不好的方式,但我正在慢慢学习如何转换代码,使其包含列表并进行操作。
我很惊讶你怎么把它缩短成这样:
回复

使用道具 举报

63

主题

6297

帖子

6283

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
358
发表于 2022-7-5 18:43:45 | 显示全部楼层
您好,Grrr,
 
列表处理和编程不能仅仅从学习中学习,你需要在实践中学习,并在例程中犯下错误,你会逐渐熟悉函数,并获得最佳性能。
正如我所见,你是AutoLISP论坛的优秀追随者,因此,试着编写代码,参与你认为能够回复或至少能够提供有用信息的每一个线程,即使其他用户编写了完整的例程。
 
如果你想成为一名合格的Lisper,请继续编码。
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-13 03:49 , Processed in 0.869319 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表