您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Visual LISP 程序设计(PPT)第3章
第3章程序的流程控制和AutoLISP文件3.1程序的流程控制AutoLISP程序的流程通过流程控制函数控制。3.1.1分支结构1.(cond(测试表达式1结果表达式1)[(测试表达式2结果表达式2)]…)该函数从第一个子表起,计算每一个子表的测试表达式,直至有一个子表的测试表达式成立为止,然后计算该子表的结果表达式,并返回这个结果表达式的值。例如,当i小于等于1时,n=1;小于等于2时,n=4;小于等于3时,n=10;其它情况下n=100。用cond函数实现变量n和i之间以上关系的源代码如下:(setqn(cond((=i1)1)((=i2)4)((=i3)10)(t100)))说明:该函数类似于C语言的switch语句,最后一个测试表达式“t(或T)”相当于C语言的“default”,指其余的情况,例如i等于5时,n等于100,也可以缺少这个测试表达式。与C语言switch语句不同的是,若某一测试表达式成立,即返回相应结果表达式的值,不再向下测试。例如,上述表达式中,若i等于0,已满足第一个测试表达式(=i1),返回结果表达式的1,最后结果是n等于1,运算结束。2.(if测试条件表达式表达式1[表达式2])若测试条件表达式结果为真,执行表达式1,否则,执行表达式2。例如:(if(a1)(setqb2))该表达式的含义是;如果a大于1,则b等于2,否则不作任何计算,求值结束。(if(a1)(setqb2)(setqb3))该表达式的含义是;如果a大于1,则b等于2,否则b等于3,求值结束。注意:该函数最多只有3个变元,即测试条件表达式、表达式1和表达式2。先分析下列程序代码:测试条件表达式表达式1成立表达式2测试条件表达式表达式1成立不成立(if(a1)(setqb2)(print(+ba))(setqb4)(printb))该程序段的本意是,若条件成立,b等于2,然后打印a与b之和,否则b等于4,然后打印b。但是在执行该程序段时,首先检查if函数变元的数量,第1个变元是测试条件表达式,它对应表达式(a1),第2个变元是条件成立时执行的表达式,它对应表达式(setqb2),第3个变元是条件不成立时执行的表达式,它对应表达式(print(+ba)),那么后面的两个表达式就是多余的变元,因此显示“toomanyarguments(变元太多)”的出错信息。若将该程序段改写为以下代码:(if(a1)((setqb2)(print(+ba)))((setqb4)(printb)))用括号将条件成立或不成立的多个表达式括起,虽然变元的数量改为3个,但会出现“error:badfunction:2”的出错信息。原因是在计算条件成立的表达式时,首先计算内层表(setqb2),将其返回值“2”作为外层表的函数名,显然这是一个坏的函数名。利用progn函数可以很好地解决了本程序段存在的问题。3.(prong表达式...)该函数将n个表达式组合起来,作为if函数的一个表达式。在执行时,按顺序计算n个表达式,返回最后一个表达式的计算结果。例如:(if(a1)(progn(setqb2)(print(+ba)))(progn(setqb4)(printb)))该程序段的执行过程是,若条件成立,b等于2,然后打印a与b之和,返回a与b之和;若条件不成立,b等于4,然后打印4,返回4。3.1.2循环结构1.(repeat整数n表达式…)重复执行n次,对所有的表达式求值,返回最后一个表达式的计算结果。例如:(setqa1b100)(repeat10(setqa(1+a))其它表达式…(setqb(+10b)))执行结果:a等于11,b等于200,返回值为200。2.(while测试式表达式…)若测试结果不为nil,执行各表达式,直至测试结果为nil。例如:(setqi1a10)(while(=i10)(setqa(+a10))其它表达式…(setqi(1+i))执行结果:i等于11,a等于110,返回值为11。例如,定义求解百钱买百鸡的函数。题目是若母鸡每只3个钱,公鸡每只2个钱,小鸡每只0.5个钱。用100个钱买100只鸡,有几个答案,每个答案各有几只母鸡、公鸡和小鸡(不包括0只),打印所求的结果。该例没有合适的计算公式,只能利用枚举,试出合适的结果。首先分析母鸡数量的范围,如果母鸡等于20,剩余40个钱。用剩下的钱至少买1只公鸡之后,可以买76只小鸡,但鸡的总数为97(小于100),所以母鸡的数量应小于20。同样,买了至少1只母鸡和32只公鸡之后,剩余的33个钱最多买66小鸡,鸡的总数为99(小于100),所以公鸡的数量应小于32。小鸡的数量只能是100减去母鸡与公鸡之和。当公鸡的数量和钱数都等于100时,打印这组解。【例3-1】解百钱买百鸡程序(defunchicken(/hencockchickcost)(setqhen1)(while(hen20);母鸡的数量不超过20(setqcock1)(while(cock32);公鸡的可能数量不超过32(setqchick(-100hencock));小鸡的数量(setqcost(+(*3hen)(*2cock)(*0.5chick)));3种鸡的钱数(if(=cost100)(print(list母鸡=hen公鸡=cock小鸡=chick)))(setqcock(1+cock));公鸡的数量加1)(setqhen(1+hen));母鸡的数量加1)(princ);静默退出)说明:①程序的第3行(setqhen1)不可缺少,否则第4行(while(hen20)中的hen将是无定义的。②第5行(setqcock1)若改写在第3行(setqhen1cock1),虽然没有语法错误,但内层循环cock的值第一次从1增加到32后,就固定为32,出现了算法错误。③程序的第12行(setqcock(1+cock))不能只写成(1+cock),表达式(1+cock)返回cock+1的值,但cock的值不变,这是1+函数与C语言++运算的不同之处。④第10行(print(list“母鸡=”hen“公鸡=”cock“小鸡=”chick))若写成(print“母鸡=”hen“公鸡=”cock“小鸡=”chick)是错误的,因为print函数只需一个变元。⑤程序结束前的(princ)表达式不返回任何值,因为它是该函数的最后一个表达式,所以该函数将不返回任何值,这样就不会干扰print函数的正常打印信息。加载该程序之后,在命令:提示下键入(chicken),输出以下结果:(母鸡=2公鸡=30小鸡=68)(母鸡=5公鸡=25小鸡=70)(母鸡=8公鸡=20小鸡=72)(母鸡=11公鸡=15小鸡=74)(母鸡=14公鸡=10小鸡=76)(母鸡=17公鸡=5小鸡=78)3.2AutoLISP程序文件3.2.1AutoLISP文件的特点AutoLISP文件的扩展名为.lsp,是由若干个AutoLISP表达式构成的。一个LISP文件可定义多个函数或AutoCAD命令。表达式相当于语句。一个表达式可以分写在若干行上,一行可以写若干个表达式。连续的多个空格相当于一个空格。以下是一个表达式分写在若干行上的实例:(defunplus(xy)(+(*xy)x))以下是一行写若干个表达式的实例:(setqa2.0)(setqb4.0)(+ab)由于在AutoLISP程序中含有大量的括号,使得程序代码不易阅读。解决这个问题的方法就是缩排对齐格式。程序代码行嵌套的层次越深,越向右缩进。例如,定义下例f(x)函数。不采用缩进格式书写,形式如下:(defunfun(x)(cond((x0)1)((=x0)2)((x0)0)))fxxxx()102000(当时)(当时)(当时)采用缩进格式书写,形式如下:(defunfun(x)(cond((x0)1)((=x0)2)((x0)0)))显然后者便于程序的阅读和调试。VisualLISP提供了文本格式编排器,可以将随意书写的程序更新为缩进格式的程序。3.3.2程序中的注释注释可增加程序的可读性,不仅便于对程序的阅读和调试,也便于对程序的维护、移植和扩充。注释的形式可以是整行、整段或行间注释。整行或后半行注释以分号“;”开头,至行尾为注释部分。例如:(setqarea(*pirr));计算圆的面积整段或行间注释以“;|”开头,以“|;”结尾,之间可以短到几个字符,长到若干行。例如,行间注释:(setqtmode;|此处添加注释|;(getvartilemode))下面是整段的注释:(setvarorthomode1);|注释起始部分连续注释,......注释到此为止|;(princ\nORTHOMODEsetOn.)【例3-2】定义打印ASCII码为33~90的字符的命令。;该程序打印ASCII码为33~90的字符;在命令提示下,键入pras(defunc:pras(/as);定义pras为AutoCAD命令,as为局部变元(setqas33);设置as为第一个ASCII码33(while(=as90);while循环开始(princ(chras));打印ASCII码的为as的字符(terpri);换新行(setqas(1+as));设置as为as的下一个ASCII码);while循环结束);命令定义结束3.2.3在AutoCAD环境下加载AutoLISP文件(1)命令行方式加载AutoLISP文件用load函数,调用load函数的格式如下:命令:(load驱动器:\\路径\\文件名[出错信息])若加载成功,返回被加载lisp文件的最后一个表达式的结果,若最后一个表达式是函数的定义,则返回该函数名。若加载失败,返回用户定义的出错信息,若用户没有定义出错信息,则返回加载失败的信息。例如,文件fi1e1.lsp最后一个表达式是定义函数func1,它的路径是d:\user1。加载该文件的表达式如下:命令:(loadd:\\user1\\fi1e1没有找到这个文件!)若加载成功,返回函数名func1,否则返回没有找到这个文件!这个信息。如果调用该函数时省略了“出错信息”,例如:命令:(loadd:/user1/fi1e1)若加载成功,返回函数名func1,否则返回;错误:LOAD失败:d:\\user1\\fi1e1.(2)对话框方式选择菜单工具加载应用程序,或者工具AutoLISP加载,或者在命令:提示下键入appload命令,都可通过随后弹出的加载/卸载应用程序对话框加载或卸载AutoLISP文件。3.自动加载AutoCAD在启动时,可以自动加载acad.lsp、acad2010.lsp、acaddoc.lsp和acad2010doc.lsp四个lisp文件。用户可以创建和维护这些文件,其中acad.lsp和acaddoc.lsp只能由用户来创建。AutoCAD在加载过程中不报告是否找到或是否加载相关文件的信息。AutoCAD在加载菜单时,自动加载了与菜单文件同名的扩展名为.mnl的lisp文件。4.间接自动加载如果把调用autoload函数的表达式写在自动加载的acad2010doc.lsp等文件内,在AutoCAD启动时,随着acad2010doc.lsp等文件的自动加载,被调用的autoload函数还可以加载一些lisp文件。调用autoload函数的格式如下:命令:(autoloadlisp文件名命令表)该函数要求lisp文件必须在AutoCAD支持的文件搜索路径下,命令表列出了在该lisp文件中定义的部份的AutoCAD命令名。无论是否加载成功,该函数均返回nil。autoload函数与load函数的不同之处是,执行完调用该函数的表达式之后,AutoCAD只是记录了被加载的lisp文件名和相应的命令表,而lisp文件本身并没有被加载。只有等到命令表内的任意一个命令被调用之后,这个lisp文件才真正被加载,这时该lisp文件所定义的全部Aut
本文标题:Visual LISP 程序设计(PPT)第3章
链接地址:https://www.777doc.com/doc-3354766 .html