You are on page 1of 751

1

AutoLISPVisual LISP

1.1 关于LISP

LISP是人工智能领域中广泛采用的一种程序设计语言。主要用于人工智

能、机器人、专家系统、博奕、定理证明等领域。

LISP也被称为符号式语言,因为它处理的对象是符号表达式。LISP语言

的程序和数据都是以符号表达式的形式来表示,因此,一个LISP程序可以把

另一个LISP程序作为它的数据来处理。

LISP语言语法简单,编写程序便捷、灵活,数据类型丰富。利用LISP

言可以很容易地定义或调用新的函数。这就是Autodesk公司早在1985年的2.1

版本就引用了LISP语言的宏操作,在1986年的2.5版本就推出了比较完整的

AutoLISP语言的原因。

LISP在它几十年的发展过程中产生了多种版本,如MacLISPInterLISP

ZetaLISP、和CommonLISP等。其中CommonLISP是近几年美国的几所大

学(如麻省理工、斯坦福等)和工业界(如Bell实验室、DEC公司、HP公司

等)的人工智能研究人员协同推出的 ,它概括了MacLISPInterLISPZetaLISP等版本的特点,因而功能较强且拥有其它版本的一些优点,是目前 LISP语言较完整的版本。

1.2 关于AutoLISP

AutoLISP是为二次开发AutoCAD而专门设计的编程语言,它起源于LISP

语言,嵌入在AutoCAD的内部,是LISP语言和AutoCAD有机结合的产物。

AutoLISP 采用了和 CommonLISP 最 相 近 的 语 法 和 习 惯 约 定 , 具 有

CommonLISP的特性,但又针对AutoCAD增加了许多功能。它既有LISP

言人工智能的特性,又具有AutoCAD强大的图形编辑功能的特点。它可以把

AutoLISP程序和AutoCAD的绘图命令透明地结合起来,使设计和绘图完全融

为一体,还可以实现对AutoCAD图形数据库的直接访问和修改。

利用AutoLISP语言可以进行各种工程分析计算、自动绘制复杂的图形,

还可以定义新的AutoCAD命令、驱动对话框、控制菜单。为AutoCAD扩充具

有一定智能化、参数化的功能,可以使设计人员的主要精力用于产品的构思

和创新设计上,实现真正意义上的计算机辅助设计。

1.3 关于Visual LISP

Visual LISPAutodesk公司在199714版本推出的。它是为 加速AutoLISP程序开发而设计的软件开发工具,是一个完整的

集成开发环境。 Visual LISP包括文本编辑器、格式编排器、语

法检查器、源代码调试器、检验和监视工具、文件编译器、工

程管理系统、上下文相关帮助与自动匹配功能和智能化控制台

等。

Visual LISP用户界面良好,用过Microsoft软件的用户只需很 短的时间即可掌握它。

Visual LISP兼容以前的AutoLISP程序。在Visual LISP集成环

境下开发AutoLISP程序,就不再象以前那样编辑程序时,用其

它系统的文本编辑程序编写程序代码;调试程序时,需要用户

自己决定在程序的什么位置插入打印语句,以便查看变量的内

容;在程序运行正常后,再将插入的调试代码删除或注释掉。

VLISP集成环境下可以便捷、高效地开发AutoLISP程序,

可以经过编译得到运行效率更高、代码更加紧凑、源代码受到

保护的应用程序。

Visual LISP是新一代AutoLISP语言,它对AutoLISP语言进行

Automation 接口与

AutoCAD对象交互,可以通过反应器函数扩展AutoLISP响应事

件的能力。

了扩展 , 可以通过 Microsoft

ActiveX

如果使用Visual LISPAutoLISP扩展功能的部份,必须调用

vl-load-com 函 数 , 或 者 将 调 用 该 函 数 的 表 达 式 写 在

acad2006doc.lsp 文件内。

2

数据类型、表达式和函数

AutoLISP的数据类型丰富,除了一般程序设计语言具有的整

型、实型、字符串等类型之外,还有表、函数、文件描述符、

AutoCAD选择集、AutoCAD图元名、VLA对象、函数分页表和

外部函数等数据类型。

2.1 数据类型

1. 整型(INT

整型即整数,整数由数字和正负号组成,正号可省略。整数

32位带符号的数字,其范围从-2147483648到+2147483647

2. 实型(REAL

实型数是带小数点的数。在-11之间的实数必须以0开头,例

如:.5是错误的,应该写成0.5。实数用双精度的浮点数表示,并

且至少有14位有效位数的精度。注意,Visual LISP不显示所有的

有效位。

3. 字符串(STR

字符串又被称为字符常数,它是由双引号括起来的字符序列

。字符串中字母的大、小写和空格符都是有意义的。

字符串中字符的个数(不包括双引号)称为字符串的长度。字

符串的最大长度为100,如果超过100,第100个字符后面的字符

将是无效的。字符串可以是空的,即"",称为空串,其长度为0

任何字符都可以用\nnn的格式表示,其中反斜杠“\ASCII

码的前导标识字符,nnn是该字符八进制的ASCII码。例如,字

符串ABCD也可表示为\101\102\123\104。一些常用的控制字符,

象反斜杠、双引号,除了可以用 \nnn的格式表示之外,还可以

用“\转义字符的格式表示为“\\、“\"”等特殊字符,见下表

2-1常用控制字符的表示方法

控制字符

用“\为前导字符

用“\为前导的ASCII码表

   

反斜杠“\

\\

\134

双引号“"

\"

\042

Esc

\e

\033

换行

\n

\012

回车键

\r

\015

Tab

\t

\011

注意,其中的字符enrt必须小写。

4.

表以左圆括号开始,以配对的右圆括号结束,表可以是空

的,可以有若干个元素;元素可以是简单的,也可以是复杂的

,还可以是其它的表。例如:(+ 1 2 3)、(sin * 0.5 pi

)、(A B)、((A BC C D))、(0 "LINE")、( 10 1.5 2.6 0.0)、()都是合法的表。

表中元素的个数称为表的长度。例如,表(+ 1 2 3)的长

度为4、表(sin * 0.5 pi))的长度为2、表((A BC

C D))的长度为3、表()的长度为0

用表可以方便地构造出复杂的数据结构,例如,(1.5 3.6

)可以表示为一个X等于1.5Y等于3.6的二维点,2.5 2.0 1.0

)可以表示为一个X等于2.5Y等于2.0Z等于1.0的三维点。

5. 函数(SUBS

函数相当于子程序或过程。函数分为内部函数和外部函数

AutoLISP提供的或用AutoLISP定义的函数为内部函数。用

ADSADSRXARX定义的函数为外部函数。例如sin cos

sqrt为内部函数。

运算符在AutoLISP里属于函数,例如“+”、“-”、

*”、“/”分别称之为加、减、乘、除函数,“<”、“<=”

、“>”分别称之为小于、小于等于和大于函数。

其它计算机语言里的子程序、过程、程序流程控制的关字 ,在AutoLISP里也属于函数,例如“if”、 “while”分别称之 为条件和条件循环函数。

6. 文件描述符(FILE

文件描述符是AutoLISP赋于被打开文件的标识号,它类似于

文件指针。下面的例子是以“读”的方式打开文件myfile.dat

并将该文件的描述符赋予符号f1

(setq f1 (open "myfile.dat" "r")) 返回<File:#34614>

7. 图元名(ENAME

图元名是AutoCAD为图形对象指定的16进制的数字标识。

AutoLISP通过该标识,找到该图形对象在图形数据库中的位

置,以便对其进行访问或编辑。

8.

选择集(PICKSET

选择集是一个或多个图形对象命名的集合 。 可以通过 AutoLISP程序建立选择集、向指定的选择集添加或移去图形对 象,通过选择集可以对其内指定的成员进行访问或编辑。

9. VLA 对象

VLA 对象是ActiveX 应用程序的主要组成部分。 不仅直线 、圆弧、多义线和圆等都被称为VLA对象,图层、组、块、视

图、视口、图形的模型空间、图纸空间、线型和尺寸标注样式

等也被称为VLA对象,甚至连AutoCAD本身也被认为是VLA

象。

2.2 变量

2.2.1 符号

符号(SYMBOL)可以理解为标识,用来作为变量、函数

的名字。它的命名规则是不能只含数字,可以由下列字符以

外的任何可打印的字符所组成:

“(”、“)”、“·”、“'”、“"”、“;”

例如,a1b2 c_3是合法的符号,(a)b.c、’4"5

是非法的符号。注意:[1]{2}~3!4/51a3c-d

+eb-2c*3也是合法的符号,这是与多数计算机语言的不

同之处。

AutoLISP中,符号的大小写等价,符号的长

度没有限制,且所有的字符都是有意义的。

如果一个符号的长度不超过6,就用节点本身来存

储;如果符号的长度超过6,这样的符号就不能用节

点来存储,而是在节点中存放一个指向实际存储符号

名的指针。这将会多占用存储空间,且减慢了执行速

度。因此,符号的长度最好不要超过6

2.2.2 变量的数据类型

AutoLISP变量属于符号,是指存储静态数据的符号。

数据类型是变量的重要的特征,因为它关系到存放变量值的

存储空间的大小。多数的计算机语言都在为变量赋值前对变量做

显式或隐式的说明。AutoLISP无须对变量做事先的类型说明,

变量被赋予值的类型即为变量的类型。

setq函数对变量赋值,例如,(setq a 5,赋值后的结果是 :变量a是整型的,因为5是整型的;同样的原因,setq b 2.5

之后, b是实型的,(setq c "ABC")之后,c就是字符串类型的。

在程序运行过程中,同一变量在不同的时刻可以被赋予

不同类型的值,因此在程序运行过程中,变量的数据类型是

可以被改变的。

例如,在一个程序里有以下两行:

setq a 5)当前的变量a是整型的。

setq a "ABC") 当前的变量a是字符串类型的。

type函数了解变量的类型,例如,(type a ) 返回INT ,显示变量a是整型的;(type b)返回REAL,显示变量b

实型的,(type c) 返回STR,显示变量c是字符串类型的。

2.2.3 为变量赋值

setq函数为变量赋值,其格式如下:

(setq 变量1 1[变量2 2

Command(setq x 1.5 y 20 p "Center")

返回“Center”

.]) 例如:

除了为变量xyp赋值外,还返回最后一个表达式的结果

Center”。如果上述表达式还有外层表达式,那么,将把该表

达式的返回值“Center”赋给外层表达式的变量。例如,

Command(setq v(setq x 1.5 y 20 p "Center") )

返回“Center”

该表达式同样为变量xyp赋值,并将内层表达式返回的结

果“Center”赋给变量v,最后返回外层表达式的结果“Center”

没有被赋值的变量属于无定义的变量

2.2.4 预定义的符号

AutoLISP对变量nilTPausePi进行了预定义,用户可以

在编写AutoLISP程序时直接使用。

1nil

如果变量没有被赋值,它的值为nilnil与空和0不同的是,

它既不是空串,也不是0值,它表示尚无定义。引用未被赋值的

变量是错误的。例如,变量x尚未被赋值,(+ 1 x)就会出现

error: bad argument type(坏的参数类型错)。

nil赋给某一有定义的变量,其结果是:取消该变量的定义

,并释放其所占存储空间。

nil作为逻辑变量的值,表示不成立,相当于其他程序设计语

言的false

2T

T为常量,它作为逻辑变量的值,表示成立,相当于其他程

序设计语言的true

3PAUSE

PAUSEcommand函数配合使用,用于暂停,等候用户输

入。

4PI

PI被定义为常量

每个变量都占用一些内存空间。为了节省存储空间,可重复

使用变量名,或者将不再使用的变量设为nil,以便释放该变量

所占的内存空间。

必须注意,一般的编程语言不允许将内部函数名

或流程控制的关键字作为变量名,而AutoLISP没有

这样的限制。因此,程序中定义的符号名称不要与系

统定义的函数名和预定义的变量名相同,否则,后面

的定义将取代已有的定义,从而引起混乱。例如,

sin是正弦函数,可是在执行表达式(setq sin 1)之后

sin不再是正弦函数,而是一个值为1的整型变量。

2.2.5 显示变量的值

要想在AutoCAD命令提示区显示变量的值,必须在变量名

前添加惊叹号!。例如了解前面已赋值的变量xv的值,操作

如下:

Command!x

1.5

Command!v

"Center"

Command!z

nil(假定变量z尚未被定义)

2.2.6 在交互方式下将变量的值传递给AutoCAD

在变量前加一个感叹号“!”,即可将表达式的值传递给

AutoCAD。例如:

Command(setq p '(20 10) r 5)

Commandcircle

: (setq p '(20 10) r 5)  Command : circle  Specify center point for

Specify center point for circle or [3P/2P/Ttr(tan tan radius)]! p

Specify radius of circle or [Diameter]:!r

即可画出圆心的坐标为(2010)半径为5的圆。

2.3 表达式

AutoLISP处理的对象是符号表达式(简称表达式)。表达式相

当于其他编程语言中程序的语句。

2.3.1 表达式的构成

表达式是由原子或表构成的。原子可细分为数原子、串原子和

符号原子。数或串原子的值是数或串本身,符号原子的值是赋给

该符号的值。例如:512.5、“ABC"是单个原子构成的表达式

多数情况下,表达式以表的形式存在,其格式如下:

(函数名 [变元])

变元的数量可能为0,也可能任意多个,这取决于具体函数。每

个参数还可以是一个表达式。

表达式形式的表,左圆括号之后的第一个元素必须是函数名。

2.3.2 表达式的前缀表示法

大多数计算机语言的表达式采用中缀表示法,即运算符在操

作数中间。如,x=2.5y=1+2

AutoLISP采用前缀表示法,将函数名放在所有操作数之前。 如,(setq x 2.5)(setq y(+ 1 2))

若将x=(a+b)*c 改写为AutoLISP表达式,则为:

(setq x(* (+ a b) c))

前缀表示法使得运算和函数调用的形式得到了统一。前面提

到,在AutoLISP语言里,运算符也属于函数。

2.3.3 表达式的求值过程

LISP语言中,函数之间不存在是否优先的关系,运算的

先后顺序只能通过表的层次来实现,最里层的表最先被求值,

把求值的结果返回给外层表,直至求值完毕。

例如,表达式(setq x(* (+ a b) c)),先求出最内层ab之和 ,然后求出ab之和与 c的积,将求得的积赋给x,最后返回x

的值。

可以在Command:提示下,输入一个表达式,AutoCAD

计算该表达式并返回计算结果。AutoCAD至多显示6位小数。

例如,在Command:提示下,键入(sin 0.5)之后回车,将

返回0.479426

如果输入的或者从文件中读入的表达式不正确,将显示出错信

息,最常见的出错信息是:

(((_>

表示缺少与左圆括号匹配的右圆括号,“(”的个数即为缺少

右圆括号的数量。如果出现该信息,输入与所提示的左圆括号相

等的右圆括号既可。由于所缺的右圆括号不一定都是最后的,所

以可能产生错误的结果。

如果遗漏了与左端双引号匹配的右端的双引号,显示的出错信

息为:

("_>

在这种情况下输入匹配的双引号也不一定使表达式能正常求值

。此时只能按Esc键终止当前的输入,重新输入表达式。

2.3.4 表达式的求值规则

1)整型数、实型数、字符串,以它们本身的值作为求值结

果。

2)符号以它们当前的约束值作为求值结果。

3)表是根据其第一个元素来进行求值的。

① 如果第一个元素或第一个元素的计算结果是一个函数名

,那么以表中剩余的元素作为该函数的变元,计算出该函数的

值。例如,表达式:

+ * 2 3) (/ 50 3))

先计算最内层的表达式(* 2 3)和 (/ 50 3),将结果6

16返回给其外层表达式,原表达式变为:(+ 6 16

② 如果第一个元素是一个表,该表不是调用而是定义函数 ,若语法正确,首先定义这个函数,然后继续表达式求值。

③ 如果第一个元素既不是函数名,也不是定义函数,将停

止求值并显示出错信息。

例如(25 a b c),将停止求值并显示“error: bad function:

25,因为25是非法的函数名,所以显示25是坏函数的出错信

息。

又比如(fx a b c) ,将停止求值并显示“error: no function definition: FX” ,指出没有定义fx这个函数。

④ 用quote函数可以禁止对表求值。

对于不需求值而直接整体引用的表,例如将一个表示三维 点的表(3 2 1)赋给变量p,如果表达式为(setq p3 2 1))

, 将中断求值过程并显示“error: bad function: 3出错信息。

因为首先对内层表求值,而内层表的第1个元素“3不是函数

名,所以停止求值。此时应该用quote函数,将表达式改为(

setq p quote3 2 1))),这样就不再对表(3 2 1)求值,

而是将将表(3 2 1)整体赋给变量p,使之表示一个3维的点。

quoteAutoLISP程序中使用最多的函数,因此该函数可用

一个单引号“'”表示。例如(quote (10 20))可以表示为'10 20

)。如果将(10 20)这个2维点赋给变量p2,可写成:

2.4 数据的存储结构

计算机的内存是由许多编了码的内存单元组成。一个特定内

存单元的编号称为内存地址。内存单元的内容是数字,也可以

是内存单元的编号,即另一内存单元的地址。如果一个内存单

元的内容是另一个内存单元的地址,那么,这个内存单元被称

为是指向另一个内存单元的指针。如果一个内存单元分为左、

右两部分,分别存放两个内存单元的地址,那么,这个内存单

元就具有左、右两个指针。

这种具有左、右两个指针的内存单元被称为节点。每个节点

的长度是12个字节,等分为左、右两部分,作为左、右指针,

每个节点都有它的地址。AutoLISP通过这样的一些节点构成链

表,以链式方式存储各种数据。

1. 符号

创建一个符号,例如(setq radius 10),至少需要3个节点。

一个节点链接到符号原子表的链尾并指向存放符号名的节点,

一个节点存放符号名和存放符号值的指针,最后一个节点存放

符号的值,见图(a)

如果符号的长度超过6字符,例如(setq fillet_radius 5),需 要申请存放符号名的存储空间,用原来存放符号名的半个节点 作为指向存放符号名的指针,见图(b)。显然要多占用一些存储

空间。

作为指向存放符号名的指针,见图 (b) 。显然要多占用一些存储 空间。

2.

字符串

字符串在内存中是以连续的空间存储的。

3.

表通过一组节点来存储。这些节点用右指针指向各自下一个元

素的地址,最后一个节点的右指针为空,用左指针指向各自的元

素。

下图依次是表(A B C D)、(A B C)(D E)) 和(setq x

+ * ab)(/ cd)))的存储结构。

(A B C D) 、( A ( B C )( D E )) 和( setq x
(A B C D) 、( A ( B C )( D E )) 和( setq x
(A B C D) 、( A ( B C )( D E )) 和( setq x

4. 点对(dotted pair

点对是一种特殊的表。若表只有两个元素,且每个元素都 是原子,这样的表可以用点对表示。点对的形式为(原子 .

子),如(0 . "LINE")、(8 . "A1")(40 . 15.0)。用一个结

点存放点对,结点的左指针指向第一个元素,右指针指向第二

个元素。图是只有两个元素(元素为原子)的表的存储结构,

图(b)是点对的存储结构。从图中不难得出结论,两个元素

都是原子的表,用点对会节省存储空间。点对的另一个特点是

简化了某些函数对表的运算。由于点对具有这些优点,因此是

AutoLISP常用的数据结构。

简化了某些函数对表的运算。由于点对具有这些优点,因此是 AutoLISP 常用的数据结构。

2.5 函数

前面提到,一般计算机语言所说的函数,AutoLISP照常称之为

函数;一般计算机语言里的子程序、过程、运算符、程序流程控

制的关键字,在AutoLISP里都被称之为函数。

AutoLISP将函数分为内部和外部函数。AutoLISP提供的或用

AutoLISP定义的函数为内部函数。用ADSADSRXARX定义

的函数为外部函数。

2.5.1 定义AutoLISP函数

定义函数用defun函数。格式如下:

(defun 函数名 (变元 / 局部变量 ) 表达式

)

函数名:函数名和变量名的命名规则相同,是代表一个函数的

符号,不应与现有的AutoLISP函数同名,否则现有函数的功能被

新定义函数的功能所取代。

变元:变元即该函数的参数,变元的数量根据实际需要而定,

可以没有变元,但不能省略一对括号“()”。

局部变量:在定义函数时,除了用到函数的参数之外,还可能

用到其他一些变量。在该域列举这些变量的名字,这些变量就

成为局部变量。局部变量是指局限于该函数内部所用的变量,

它只在该函数调用期间得到定义,函数调用结束,局部变量的

值均为nil,同时释放其所占存储空间。如果不作声明,它们将

成为全程变量,即使函数调用结束,仍然保留各自的值,可被

其他函数所存取,直至退出当前的图形文件。进行局部变量声

明不仅可以节省存储空间,而且可以避免函数之间相互干扰。

局部变量与变元之间用除号隔开,即使没有变元,也可以有局

部变量说明,但前面要有除号。

表达式:表达式的数量不限,用于描述该函数的运算。

函数的返回值:最后一个表达式的返回值即为该函数的返回

值。

【例2-1】定义一个加10函数,源代码如下:

(defun add10(x)

(setq x(+ 10 x))

)

或者:

(defun add10(x)

)

(+

10 x)

该函数的函数名是add10,只有一个变元x,没有局部变量说

明,它返回表达式(setq x(+ 10 x))(+ 10 x)的值(二者是相

等的)。

【例2-2】定义一个已知圆柱体的半径和高度,计算其

体积的函数。源代码如下:

(defun volume(r h / v)

)

(setq v(*

r

r

pi

h))

该函数的函数名是volume ,有两个变元r(半径)和h (高度),有一个局部变量v,它返回表达式(setq v(* r r pi h))的值。

2.5.2 调用AutoLISP函数

AutoLISP以表的形式调用函数,其格式如下:

(函数名 [变元])

表的第一个元素是函数名,其余是该函数所要求的变元,变元

的数量可能为0,也可能任意多个,这取决于具体函数。例如,

sqrt 4),调用的函数名为sqrt(求平方根),函数的变元是4 、只有一个变元;

+ 1 2 3),调用的函数名为“+”(加),函数的变元是12

3,共有3个变元。

每个变元还可以是一个表达式。例如:

每调用一个函数,都会得到函数的返回值。例如,

sqrt 4, 返回2 + 1 2 3, 返回6 有些函数返回逻辑常数Tnil,例如,

< 1 2, 返回T; (not 1),返回nil。 调用自定义的函数与调用系统提供的函数的格式相同。例如, add10 3

(setq y(add10 (+ 2 3))) (volume 12.5 20)1)

2.5.3 递归调用AutoLISP函数

AutoLISP可以在一个函数的内部定义另一个函数,可以递归

定义和调用函数。

【例2-3】定义阶乘函数

阶乘的定义是,0的阶乘等于1n的阶乘等于nn-1)的阶

乘。程序的源代码如下:

(defun factorial(x)

(if (= x 0)

1

(* x (factorial (- x 1)))

)

2.5.4 调用AutoCAD命令

AutoLISPcommand函数调用AutoCAD命令,其格式如下:

command “AutoCAD命令” "命令所需的数据" )

【例2-4】绘制以(2,4)为圆心,5为半径的圆。

command "circle" "2,4" 5)或者

command "circle" „(2 4) 5)

【例2-5】已知p1p2p3为不在同一直线上的三个点,利用这

三个点画圆。

command "circle" "3p" p1 p2 p3)

【例2-6】画从点p100)到点p2100)的一段直线。

command "line“ "0,0"10,0"")或者

command "line" '(0 0) '(10 0) "")或者

command "line" (list 0 0) (list 10 0) "")或者

command "line“ p1 p2 "");假定p1p2是两个点

注意:因为绘制直线时用空回车或空格响应 “Specify next point or [Undo]:提示才能结束line命令,所以在最后一个点的后面要 增加两个双引号,代表一个回车或空格。

2.5.5 定义AutoCAD命令

定义AutoCAD命令用defun函数。格式如下:

(defun C:AutoCAD命令名 (/ 局部变量

)表达式

)

定义AutoCAD命令与定义函数基本相同,不同之处是

命令名前加“C:

没有变元,但可以有局部变量说明。

此外要注意所定义的 AutoCAD命令不应与现有的 AutoCAD命令同名。

【例2-7】定义输入矩形的对角点绘制矩形的命令。

源代码如下:

(defun c:rect1( / p1 p2 p3 p4) p1p2p3p4是局部变元

(setq p1 (getpoint "\n输入矩形的一个角点" ))

(setq p3 (getcorner p1 "\n输入矩形的另一个角点:" ))

(setq p2(list (car p3) (cadr p1)))

p4

p3

(setq p4(list (car p1)(cadr p3)))

(command "pline" p1 p2 p3 p4 "c")

 

p1

p2

)

加载含有以上代码的程序后,在AutoCADCommand:命

令提示下,象调用普通命令一样键入rect1,即可调用自定义的

绘制矩形的命令(见下图)

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 之间以上关系的源代码如下:

成立

测试表达式1 测试表达式2 测试表达式n
测试表达式1
测试表达式2
测试表达式n
结果表达式1 不成立 成立 结果表达式2 不成立 成立 结果表达式n 不成立
结果表达式1
不成立
成立
结果表达式2
不成立
成立
结果表达式n
不成立
成立 测试表达式1 结果表达式1 不成立 成立 测试表达式2 结果表达式2 不成立 成立
成立
测试表达式1
结果表达式1
不成立
成立
测试表达式2
结果表达式2
不成立
成立
测试表达式n
结果表达式n
不成立
T(其余)
结果表达式

(setq n(cond ((<= i 1) 1)

)

)

((<= i

((<= i

(t 100)

2) 4)

3) 10)

说明:该函数类似于C语言的switch语句, 最后一个测试表达 式“t(或T)”相当于C语言的“default”,指其余的情况,例如

i 等于5时,n等于100,也可以缺少这个测试表达式。与C语言

switch语句不同的是,若某一测试表达式成立,即返回相应结果 表达式的值,不再向下测试。例如,上述表达式中,若i 等于0 ,已满足第一个测试表达式(<= i 1),返回结果表达式的1,最

后结果是n等于1,运算结束。

2.if 测试条件表达式 表达式1 [表达式2]

若测试条件表达式结果为真,执行表达式1,否则,执行表达

2。例如:

(if

该表达式的含义是;如果a 大于 1,则b等于2,否则不作任何 计算,求值结束。

(if (>

该表达式的含义是;如果a 大于 1,则b等于2,否则b等于3, 求值结束。

注意:该函数最多只有3个变元,即测试条件表达式、表达式1

表达式2。先分析下列程序代码:

(> a 1) (setq b 2) )

a 1) (setq b 2) (setq b 3) )

测试条件 表达式 成立 表达式1
测试条件
表达式
成立
表达式1
测试条件 表达式 成立 不成立 表达式1 表达式2
测试条件
表达式
成立
不成立
表达式1
表达式2

(if (> a 1)

(setq b 2)

(print (b a))

(setq b 4)

(print b)

)

该程序段的本意是,若条件成立,b等于2,然后打印ab

和,否则b等于4,然后打印b。但是在执行该程序段时,首先检

if函数变元的数量,第1个变元是测试条件表达式,它对应表

达式(> a 1),第2个变元是条件成立时执行的表达式,它对应表

达式(setq b 2),第3个变元是条件不成立时执行的表达式,它对 应表达式(print (b a)) ,那么后面的两个表达式就是多余的变 元,因此显示“too many arguments(变元太多)”的出错信息

若将该程序段改写为以下代码:

(if (>

1)

a

((setq b 2)

(print (b a))

)

((setq b 4)

(print b)

)

)

用括号将条件成立或不成立的多个表达式括起,虽然变元的 数量改为3个,但会出现“error: bad function: 2的出错信息。原 因是在计算条件成立的表达式时,首先计算内层表(setq b 2)

将其返回值“2作为外层表的函数名,显然这是一个坏的函数

名。利用progn函数可以很好地解决了本程序段存在的问题

3.

(prong 表达式

)

该函数将n个表达式组合起来,作为if函数的一个表达式。在

执行时,按顺序计算n个表达式,返回最后一个表达式的计算结果

。例如:

(if (> a

1)

(progn (setq b 2)

(print (b a))

)

(progn (setq b 4)

)

)

(print b)

该程序段的执行过程是,若条件成立,b等于2,然后打印a

b之和,返回ab之和;若条件不成立,b等于4,然后打印4,返

4

3.1.2 循环结构

1. (repeat 整数n 表达式 )

重复执行n次,对所有的表达式求值,返回最后一个表达式的

计算结果。例如:

1

(repeat 10

(setq a

b 100)

计算结果。例如: 1 (repeat 10 (setq a b 100) (setq 其它表达式 … (setq b(+ 10 b)) a(

(setq

其它表达式

(setq b(+ 10 b))

a(+ 1

a))

)

执行结果:a等于11b等于200,返回值为200

2. (while 测试式 表达式 )

若测试结果不为nil,执行各表达式, 直至测试结果为nil。例如:

(setq i

1

10)

a

(while (<= i 10)

(setq

其它表达式

a(+ a

10))

(setq

i (1+

i )

)

执行结果:i等于11a等于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】解百钱买百鸡程序

(defun chicken( / hen cock chick cost)

(setq hen 1) (while (< hen 20);母鸡的数量不超过20 (setq cock 1) (while (< cock 32);公鸡的可能数量不超过32 (setq chick (- 100 hen cock));小鸡的数量

(if (= cost 100)

(print (list "母鸡=" hen " 公鸡=" cock " 小鸡=" chick))

)

(setq cock (1+ cock));公鸡的数量加1

(setq cost (+ (* 3 hen)(* 2 cock)(* 0.5 chick)))3种鸡的钱数

)

(setq hen (1+ hen)) ;母鸡的数量加1

)

(princ);静默退出

说明:

① 程序的第3(setq hen 1)不可缺少,否则第4(while (< hen 20) 中的hen将是无定义的。

② 第5(setq cock 1)若改写在第3(setq hen 1 cock 1),虽然没

有语法错误,但内层循环cock的值第一次从1增加到32后,就固

定为32,出现了算法错误。

③ 程序的第12(setq cock (1+ cock))不能只写成(1+ cock),表达

(1+ cock)返回cock+1的值,但cock的值不变,这是1+ 函数与C 语言 ++ 运算的不同之处。

④ 第10(print (list 母鸡=” hen 公鸡=” cock 小鸡=” chick))

写成(print 母鸡=” hen 公鸡=” cock 小鸡=” chick)是错误的, 因为print函数只需一个变元。

⑤ 程序结束前的(princ)表达式不返回任何值,因为它是该函数的

最后一个表达式,所以该函数将不返回任何值,这样就不会干扰

print函数的正常打印信息。

加载该程序之后,在“Command:提示下键

(chicken),输出以下结果:

("母鸡=" 2 " 公鸡=" 30 " 小鸡=" 68)

("母鸡=" 5 " 公鸡=" 25 " 小鸡=" 70)

("母鸡=" 8 " 公鸡=" 20 " 小鸡=" 72)

("母鸡=" 11 " 公鸡=" 15 " 小鸡=" 74)

("母鸡=" 14 " 公鸡=" 10 " 小鸡=" 76)

("母鸡=" 17 " 公鸡=" 5 " 小鸡=" 78)

3.2 AutoLISP程序文件

3.2.1 AutoLISP文件的特点

AutoLISP文件的扩展名为.lsp,是由若干个AutoLISP表达式

构成的。

一个LISP文件可定义多个函数或AutoCAD命令。

表达式相当于语句。一个表达式可以分写在若干行上,一

行可以写若干个表达式。连续的多个空格相当于一个空格。以

下是一个表达式分写在若干行上的实例:

(defun plus(x y)

(+ (* x y) x)

)

以下是一行写若干个表达式的实例:

(setq a 2.0) (setq b 4.0) (+ a b)

由于在AutoLISP程序中含有大量的括号,使得程序代

码不易阅读。解决这个问题的方法就是缩排对齐格式

。程序代码行嵌套的层次越深,越向右缩进。例如,

定义下例 f(x)函数。

f

(

x

)

(当

1

(当

2

  (当

0

x

x

x

0

时)

0

时)

0

时)

不采用缩进格式书写,形式如下:

采用缩进格式书写,形式如下:

(defun fun(x)

(cond((> x 0)

1)

((=

x

0)

2)

((<

x

0)

0)

)

)

显然后者便于程序的阅读和调试。Visual LISP提 供了文本格式编排器,可以将随意书写的程序更新 为缩进格式的程序。

3.3.2 程序中的注释

注释可增加程序的可读性,不仅便于对程序的阅读和调试,

也便于对程序的维护、移植和扩充。

注释的形式可以是整行、整段或行间注释。

整行或后半行注释以分号“;”开头,至行尾为注释部分。例如 :(setq area (* pi r r)) ; 计算圆的面积

整段或行间注释以“;|”开头,以“|;”结尾,之间可以短到几

个字符,长到若干行。例如,行间注释:

(setq tmode |此处添加注释|(getvar "tilemode"))

下面是整段的注释:

(setvar "orthomode" 1) |注释起始部分

连续注释,

.

注释到此为止|(princ "\nORTHOMODE set On.")

.

【例3-2】定义打印ASCII码为33 ~ 90的字符的命令。

;该程序打印ASCII码为33 ~ 90的字符

;在Command:提示下,键入pras

(defun c:pras(/ as ) (setq as 33) (while(<= as 90) (princ(chr as)) (terpri)

(setq as (1+ as))

)

;定义prasAutoCAD命令,as为局部变元

;设置as为第一个ASCII33

while循环开始

;打印ASCII码的为as的字符

;换新行

;设置asas 的下一个ASCII

while循环结束

3.2.3 AutoCAD环境下加载AutoLISP文件

1)命令行方式

加载AutoLISP文件用load函数,调用load函数的格式如下:

Command(load "驱动器:\\路径\\文件名" ["出错信息

"])

若加载成功,返回被加载lisp文件的最后一个表达式的结果

,若最后一个表达式是函数的定义,则返回该函数名。若加载

失败,返回用户定义的出错信息,若用户没有定义出错信息,

则返回加载失败的信息。

例如,文件fi1e1.lsp最后一个表达式是定义函数func1,它的

路径是d:\user1。加载该文件的表达式如下:

Command(load "d:\\ user1\\ fi1e1" "没有找到这个文 件!" )

若加载成功,返回函数名func1,否则返回"没有找到这个文件

"这个信息。

如果调用该函数时省略了“出错信息”,例如:

Command(load "d:/ user1/fi1e1")

若加载成功,返回函数名func1,否则返回; error: LOAD

failed: " d:\\ user1\\ fi1e1".

2)对话框方式

选择下拉菜单ToolsLoad Application ,或者选择下拉菜单 ToolsAutoLISPLoad,或者在“Command:”提示下键入

appload,通过随后弹出的“Load/Unload Applications对话框加载

AutoLISP文件。

:”提示下键入 appload ,通过随后弹出的“ Load/Unload Applications ” 对话框加载 AutoLISP 文件。

3. 自动加载

AutoCAD 在启动时 , 可以自动加载 acad.lsp acad2006.lsp acaddoc.lsp acad2006doc.lsp

lisp文件。用户可以创建和维护这些文件,其中

acad.lsp acaddoc.lsp 只 能 由 用 户 来 创 建 。

AutoCAD在加载过程中不报告是否找到或是否加载相

关文件的信息。AutoCAD在加载菜单时,自动加载了

与菜单文件同名的扩展名为.mnllisp文件。

4. 间接自动加载

如果把调用autoload函数的表达式写在自动加载

acad2006doc.lsp等文件内,在AutoCAD启动时,随

acad2006doc.lsp 等文件的自动加载 , 被调用的 autoload 函 数 还 可 以 加 载 一 些 lisp 文 件 。 调 用

autoload函数的格式如下:

Command(autoload lisp文件名 命令表)

该函数要求lisp文件必须在AutoCAD支持的文件搜

索路径下,命令表列出了在该lisp文件中定义的部份

AutoCAD命令名。无论是否加载成功,该函数均返

nil

autoload函数与load函数的不同之处是,执行完调用该函

数的表达式之后,AutoCAD只是记录了被加载的lisp文件名和

相应的命令表,而lisp文件本身并没有被加载。只有等到命令

表内的任意一个命令被调用之后,这个lisp文件才真正被加载

,这时该lisp文件所定义的全部AutoCAD命令才处于可以被调

用状态。也就是说,如果某个lisp文件所定义的命令没有被调

用,那么这个lisp文件就暂时不被加载到内存,从而节省了内

存空间。

例如 , 文件 file1.lsp 定义了 “ cmd1、 “ cmd2等多个

AutoCAD命令,该文件存放在 AutoCAD support目录下。用

autoload加载file1.lsp的表达式如下:

AutoCAD 命令,该文件存放在 AutoCAD 的 support 目录下。用 autoload 加载 file1.lsp 的表达式如下:

Command (autoload

"file1.lsp"

"cmd1"

"cmd2")

此后如果调用file1.lsp文件定义的命令表之外的命

令,会显示“Unknown command(未知命令)"×××".的出错信息,因为该lisp文件尚未被真正地加载。如果

调用命令表内的任意一个命令,例如调用cmd1命令,

file1.lsp文件才被AutoCAD真正地加载,随后该文件定

义的所有AutoCAD命令均可被调用。

如果将表达式(autoload " file1.lsp" "cmd1"

"cmd2"),追加到acad2006doc.lsp等文件的后面,即

可在启动AutoCAD时,间接自动地加载了file1.lsp

4

有关Visual LISP的基本操作

4.1 进入和退出Visual LISP

1. 进入Visual LISP

AutoCAD 下 拉 菜 单 中 选 择 ToolsAutoLISPVisual

LISP Editor,或在命令提示“Command:”下键入vlide

即可进入下图所示的Visual LISP集成环境。

2. 退出Visual LISP

Visual LISP下拉菜单中选择FileExit或单击其所在窗 口的关闭按钮即可。注意此时AutoCAD并没有完全卸载Visual

LISP,而只是把所有的Visual LISP窗口关闭。

在下一次启动Visual LISP任务时,Visual LISP将自动打

开上次退出时打开的文件和窗口。

3. 切换到AutoCAD窗口

除了使用标准的Windows的窗口切换方法之外,还可以在

Visual LISP下拉菜单选择WindowActivate AutoCAD或单击

View工具栏中的按钮

LISP 下拉菜单选择 W indow  Activate A utoCAD 或单击 View 工具栏中的按钮 来激活 AutoCAD 窗口。

来激活AutoCAD窗口。

4.2 Visual LISP的用户界面

4.2 Visual LISP 的用户界面

1)菜单

( 1 )菜单 Visual LISP 提供了 9 个下拉菜单,每个菜单的详细内容与 当前的工作状态相关。

Visual LISP提供了9个下拉菜单,每个菜单的详细内容与

当前的工作状态相关。

File:创建新的或修改已有的AutoLISP程序文件,编译或打印

程序文件等。

Edit:复制和粘贴文本,匹配表达式中的括号,或复制控制台

窗口内以前的输入等。

Search:查找和替换文本字符串,设置书签,或利用书签导航

等。

View:查找和显示程序代码中的变量和符号值等。

Project:使用工程和编译、链接程序等。

Debug:调试程序,检查变量状态和表达式的结果。

Tools:设置Visual LISP文本格式化选项和各种环境选项等。

Window:窗口管理。

Help:在线帮助。

2)工具栏

Visual LISP提供了StandardViewDebugToolsSearch五 个工具栏 。

Standard工具栏

建立一个新文件和 Search 五 个工具栏 。 ① Standard 工具栏 存盘 剪切 粘贴 恢复 打开一个已有的文件

存盘。 ① Standard 工具栏 建立一个新文件 剪切 粘贴 恢复 打开一个已有的文件

剪切。 ① Standard 工具栏 建立一个新文件 存盘 粘贴 恢复 打开一个已有的文件 打印输出

粘贴① Standard 工具栏 建立一个新文件 存盘 剪切 恢复 打开一个已有的文件 打印输出 复制

恢复工具栏 建立一个新文件 存盘 剪切 粘贴 打开一个已有的文件 打印输出 复制 取消

工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打开一个已有的文件 打印输出 复制 取消

打开一个已有的文件。 ① Standard 工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打印输出 复制 取消 完词功能

打印输出工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打开一个已有的文件 复制 取消 完词功能

复制工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打开一个已有的文件 打印输出 取消 完词功能

取消工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打开一个已有的文件 打印输出 复制 完词功能

完词功能工具栏 建立一个新文件 存盘 剪切 粘贴 恢复 打开一个已有的文件 打印输出 复制 取消

Tools工具栏

② Tools 工具栏 装入当前编辑窗口的全部程序 装入选取的部分程序

装入当前编辑窗口的全部程序② Tools 工具栏 装入选取的部分程序 对当前编辑窗口的全部程序语进行法检查

装入选取的部分程序② Tools 工具栏 装入当前编辑窗口的全部程序 对当前编辑窗口的全部程序语进行法检查

对当前编辑窗口的全部程序语进行法检查装入选取的部分程序 对选取的程序进行语法检查

对选取的程序进行语法检查对当前编辑窗口的全部程序语进行法检查 对当前编辑窗口的全部程序格式化

对当前编辑窗口的全部程序格式化对选取的程序进行语法检查 对选取的程序进行格式化

对选取的程序进行格式化对当前编辑窗口的全部程序格式化 将所选部分变为注释块

将所选部分变为注释块对选取的程序进行格式化 取消所选注释块的注释作用 在线帮助

取消所选注释块的注释作用对选取的程序进行格式化 将所选部分变为注释块 在线帮助

在线帮助对选取的程序进行格式化 将所选部分变为注释块 取消所选注释块的注释作用

View工具栏

③ View 工具栏 切换到 AutoCAD 图形窗口 确定活动窗口 激活控制台窗口 打开检测窗口

切换到AutoCAD 图形窗口 AutoCAD图形窗口

确定活动窗口③ View 工具栏 切换到 AutoCAD 图形窗口 激活控制台窗口 打开检测窗口 堆栈跟踪功能 符号服务

激活控制台窗口工具栏 切换到 AutoCAD 图形窗口 确定活动窗口 打开检测窗口 堆栈跟踪功能 符号服务 匹配

打开检测窗口AutoCAD 图形窗口 确定活动窗口 激活控制台窗口 堆栈跟踪功能 符号服务 匹配 打开监视窗口

堆栈跟踪功能AutoCAD 图形窗口 确定活动窗口 激活控制台窗口 打开检测窗口 符号服务 匹配 打开监视窗口

符号服务图形窗口 确定活动窗口 激活控制台窗口 打开检测窗口 堆栈跟踪功能 匹配 打开监视窗口

匹配确定活动窗口 激活控制台窗口 打开检测窗口 堆栈跟踪功能 符号服务 打开监视窗口

打开监视窗口AutoCAD 图形窗口 确定活动窗口 激活控制台窗口 打开检测窗口 堆栈跟踪功能 符号服务 匹配

Search工具栏

④ Search 工具栏 查找 替换 查找并且替换 设置或取消书签切换 到下一个书签的位置

查找④ Search 工具栏 替换 查找并且替换 设置或取消书签切换 到下一个书签的位置

替换④ Search 工具栏 查找 查找并且替换 设置或取消书签切换 到下一个书签的位置

查找并且替换④ Search 工具栏 查找 替换 设置或取消书签切换 到下一个书签的位置 到上一个书签的位置

设置或取消书签切换④ Search 工具栏 查找 替换 查找并且替换 到下一个书签的位置 到上一个书签的位置

到下一个书签的位置工具栏 查找 替换 查找并且替换 设置或取消书签切换 到上一个书签的位置 清除所有的书签

到上一个书签的位置工具栏 查找 替换 查找并且替换 设置或取消书签切换 到下一个书签的位置 清除所有的书签

清除所有的书签查找 替换 查找并且替换 设置或取消书签切换 到下一个书签的位置 到上一个书签的位置

Debug工具栏

⑤ Debug 工具栏 执行一步 执行一个表达式 执行一个过程 继续执行 退出当前层 重置为顶层

执行一步⑤ Debug 工具栏 执行一个表达式 执行一个过程 继续执行 退出当前层 重置为顶层

执行一个表达式⑤ Debug 工具栏 执行一步 执行一个过程 继续执行 退出当前层 重置为顶层 设置或取消断点

执行一个过程⑤ Debug 工具栏 执行一步 执行一个表达式 继续执行 退出当前层 重置为顶层 设置或取消断点

继续执行执行一步 执行一个表达式 执行一个过程 退出当前层 重置为顶层 设置或取消断点

退出当前层执行一个表达式 执行一个过程 继续执行 重置为顶层 设置或取消断点 添加监视

重置为顶层执行一个过程 继续执行 退出当前层 设置或取消断点 添加监视 显示上一个断点

设置或取消断点执行一个过程 继续执行 退出当前层 重置为顶层 添加监视 显示上一个断点 调试指示器按钮

添加监视继续执行 退出当前层 重置为顶层 设置或取消断点 显示上一个断点 调试指示器按钮

显示上一个断点执行一个过程 继续执行 退出当前层 重置为顶层 设置或取消断点 添加监视 调试指示器按钮

调试指示器按钮执行一个过程 继续执行 退出当前层 重置为顶层 设置或取消断点 添加监视 显示上一个断点

3)文本编辑窗口

Visual LISP 的 文 本 编 辑窗口除了具有一般文本编

辑器的全部功能外,还具有

适于AutoLISP的一些专用功

能。可以实现对AutoLISP

序的编辑、调试、检测、编

译、运行等工作。

的一些专用功 能。可以实现对 AutoLISP 程 序的编辑、调试、检测、编 译、运行等工作。

4)控制台窗口

控制台窗口是Visual LISP主窗口中一个独立的可滚动窗口。 其形式与AutoCAD命令提示与信息反馈窗口类似。在控制台窗 口内可以输入AutoLISP表达式,也可以不用菜单或工具栏而

直接在控制台窗口发出Visual LISP命令。

AutoLISP 表达式,也可以不用菜单或工具栏而 直接在控制台窗口发出 Visual LISP 命令。
AutoLISP 表达式,也可以不用菜单或工具栏而 直接在控制台窗口发出 Visual LISP 命令。

5)状态行

位于屏幕底部,显示与Visual LISP所做工作相关的信息。例如在编辑程序 时,显示“Edit: d:/lisp1/roots.lsp * 等信息,显示当前正在编辑文件

的路径的名称,若文件名之后有一个“* ”,表示该文件尚未保存最新的结

果;若切换到控制台窗口时,显示Visual LISP console window;若切换到

跟踪窗口时,显示Trace output window;若关闭停留在菜单项或工具栏按钮

时,显示相应菜单项或工具栏按钮的简短的帮助信息。在状态行的右端显示

着光标当前处于窗口第几行、第几个字符的信息。

( 6 )跟踪窗口

6)跟踪窗口

跟踪窗口通常处于最小化的状态。在启动时,该窗口包含Visual LISP

前版本的信息,如果Visual LISP在启动时遇到错误,它还会包含相应的错误

信息。

LISP 当 前版本的信息,如果 Visual LISP 在启动时遇到错误,它还会包含相应的错误 信息。

4.3 控制台操作

控制台窗口与 AutoCAD 命令窗口只是形式上类似 , 不但其功能多于 AutoCAD命令窗口,即使是相同的功能部分,其操作也有所不同。

1. 控制台窗口与AutoCAD命令窗口的区别

① 控制台窗口的命令提示符为_$

② 空格键只是空格,不再代替回车,只有按下回车键,系统才对表达式 求值;

③ 按Ctrl+Enter键,可以将未输入完的表达式续写到下一行;

④ 按Esc键,取消当前的输入,按Shift+Esc键,出现控制台新的提示_$

⑤ 查看变量值不用在变量前加惊叹号“”;

⑥ 在键入Enter键之前可输入多个表达式,并返回输入的每个表达式的 值;

⑦ 调用自定义的AutoCAD命令的格式为(C: 自定义的AutoCAD命令名)

调用普通函数的格式仍然为(函数名 参数 )。

操作举例:

_$(setq a 1 b 2 Ctrl+Enter键续写到下一行

c 3 d 4) (setq e 5) 此例输入了两个表达式,按Enter键对表达式求值

4 返回第一个表达式的值为4

5 返回第二个表达式的值为5

_$

2. 使用控制台窗口的历史记录

_$提示下,每按一次Tab键,回溯前一次输入的字符串,作为当前输入。

到了第一次输入的字符串时,再按Tab键,返回最后一次输入的字符串,周

而复始。每按一次Shift+Tab键时,将进行反向回溯。

3. 控制台快捷菜单

为了快速调用控制台窗口的一些最重要的功能,Visual LISP提供了下图

所示相应的快捷菜单。在控制台窗口的任何地方单击鼠标右键或按Shift+F10

即可显示该快捷菜单。快捷菜单中的某些菜单项是否处于可用状态,还与当

前的文本操作有关。

也可以在Visual LISP控制台窗口和AutoCAD命令窗口之间剪切和粘贴文本。

删除被选中的文本并将其移到 Windows 剪贴板 将选中的文本复制到剪贴板中

删除被选中的文本并将其移到Windows剪贴板

将选中的文本复制到剪贴板中

将剪贴板内容粘贴到光标位置

清空控制台窗口

在控制台窗口中查找指定文本

打开“检验”对话框

打开“监视”窗口

打开“自动匹配选项”窗口

打开“符号服务”对话框

放弃最近的操作

重新执行上次放弃的操作

将所有输入传送到 AutoCAD 命令行以供求值

切换是否将控制台窗口的输出复制到日志文件

控制台快捷菜单

4. 记录控制台窗口的活动

日志文件的文件类型为“.log

它记录了控制台窗口的所有活动,通

过浏览该文件可以回顾控制台窗口中

执行的命令。

在 控 制 台 窗 口 通 过 下 拉 菜 单

FileToggle Console Log或快捷菜单

口 通 过 下 拉 菜 单 F ile  To g gle Console Log 或快捷菜单

Toggle Console Log可以建立日志文件。

4.4 文件操作

1. 建立一个新文件

4.4 文件操作 1. 建立一个新文件 选择菜单 F ile  N ew File 或同时按下 Ctrl + N 键或点取按钮

选择菜单FileNew File或同时按下Ctrl+N键或点取按钮 ,将弹出一个 空的文本编辑器窗口,用来建立一个新文件。

2. 打开一个已有的文件

选择菜单FileOpen File或同时按下Ctrl+O键或点取按钮

 O pen File 或同时按下 Ctrl + O 键或点取按钮 ,将弹出 Open file to edit/view

,将弹出

Open file to edit/view对话框,输入文件名,即可将指定的文件装入新的文本

编辑窗口,并在状态栏上显示文件名。如果对该文件进行了修改,Visual

LISP将在状态行的该文件名前显示一个星号“*”,直到该文件存盘,星号

才会消失。

可以同时编辑多个文件。每打开一个文件,Visual LISP都在新的文本编辑

器窗口中显示文件。

3. 重新打开文件

选择菜单FileRepen

可以在其下一级菜单选择

曾经打开过的文件。

4. 建立文件的备份

曾经打开过的文件。 4. 建立文件的备份 Visual LISP

Visual LISP可自动建立由文本编辑器加载文件的备份。实际 的备份操作是在第一次保存文件时执行的。备份文件与原文件

同名,后缀以下划线“_开头,后跟原后缀中的前两个字符。

5. Visual LISP环境下加载AutoLISP程序

加载AutoLISP程序的目的是运行AutoLISP程序。在Visual

LISP环境下,可以加载完整的和局部的AutoLISP程序文件。

1)加载完整的AutoLISP程序文件

选择菜单FileLoad FiLe,在随后 弹出的Load lisp file对话框内输入

AutoLISP文件名。若程序没有语法错

误,在控制台窗口显示下图(a)所示

信息,表示加载成功。若程序存在语

法错误,在控制台窗口程序出错的信

息,见下图(b),表示加载不成功。

该操作与3.2节介绍的在AutoCAD环境

下加载AutoLISP文件的操作是等效的。

该操作与 3.2 节介绍的在 AutoCAD 环境 下加载 AutoLISP 文件的操作是等效的。
a 加载成功 b 有语法错误 图 4-3 加载 AutoLISP 程序文后件控制台窗口显示的信息

a 加载成功

a 加载成功 b 有语法错误 图 4-3 加载 AutoLISP 程序文后件控制台窗口显示的信息

b 有语法错误

4-3加载AutoLISP程序文后件控制台窗口显示的信息

2)在Visual LISP文本编辑窗口加载完整的AutoLISP程序

选择菜单ToolsLoad Text in Editor或点取Tools工具栏的按 钮 ,即可加载活动窗口内的AutoLISP程序。

钮 ,即可加载活动窗口内的 AutoLISP 程序。 ( 3 )在 Visual LISP 文本编辑窗口加载局部的

3)在Visual LISP文本编辑窗口加载局部的AutoLISP程序

亮 显 部 分 的 AutoLISP 程 序 或 一 些 表 达 式 , 选 择 菜 单

程 序 或 一 些 表 达 式 , 选 择 菜 单 ,即可加 载所选的 AutoLISP

,即可加

载所选的AutoLISP程序或表达式。该操作可以检查所选的表

达式是否存在语法错误,也可以看到所选的表达式的运算结果。

ToolsLoad Selection或点取Tools工具栏的按钮

5

编辑源程序代码

5.1 文本编辑工具

与文本编辑有关的下拉菜单有FileEditSearch

File 、 Edit 和 Search 。 工具栏有 Standard 、 Search 和 Tools 。

工具栏有StandardSearchTools

、 Edit 和 Search 。 工具栏有 Standard 、 Search 和 Tools 。 此外还有专用的快捷菜单和快捷键。
、 Edit 和 Search 。 工具栏有 Standard 、 Search 和 Tools 。 此外还有专用的快捷菜单和快捷键。
、 Edit 和 Search 。 工具栏有 Standard 、 Search 和 Tools 。 此外还有专用的快捷菜单和快捷键。

此外还有专用的快捷菜单和快捷键。

1. 文本编辑器的快捷菜单

在文本编辑器窗口单击鼠标右键,将弹出图5-1所示文本编辑器的快捷菜单。

5-1 所示文本编辑器的快捷菜单。 删除被选中的文本并将其移到 Windows 剪贴板

删除被选中的文本并将其移到 Windows 剪贴板 将选中的文本复制到剪贴板Windows 剪贴板 将剪贴板内容粘贴到光标位置 在一个或多个文本编辑器窗口中查找指定文本 将光标移到最近编辑的位置

在光标位置处以跟斗式设置删除一个断点

打开“检验”对话框

打开“监视”窗口

打开“自动匹配选项”窗口

打开“符号服务”对话框

放弃最近的操作

重新执行上次放弃的操作

5-1文本编辑器的快捷菜单

2. 文本编辑器的快捷键

1)光标移动快捷键

除了使用方向按键之外,还可以使用表5-1所示一些组合的快捷键来移动光标。

5-1光标移动快捷键

快捷键

光标的动作

Ctrl +

向左移动一个词

Ctrl +

向右移动一个词

End

移到行末

Home

移到行首

PgDn

下移一屏

PgUp

上移一屏

Ctrl + End

移到文档最后

Ctrl + Home

移到文本开始处

Ctrl + [

移到与光标相匹配的左括号之前

Ctrl + ]

移到与光标相匹配的右括号之后

2)文本选取快捷键

除了双击鼠标左键,选取那些由光标位置决定的文本之外,还可使用表 5-2所示文本选取快捷键。 表5-2 文本选取快捷键

快捷键

功能

Shift +

选取该字符开始到下一行该字符位置之前的所有字符

Shift +

选取该字符开始到上一行该字符位置之后的所有字符

Shift + End

选取该字符开始到行末的所有字符

Shift + Home

选取该字符开始到行首的所有字符

Shift + PgDn

选取该字符开始到下一页该字符位置之前的所有字符

Shift + PgUp

选取该字符开始到上一页该字符位置之后的所有字符

Ctrl + Shift +

选取该字符开始到该词结束的所有字符

Ctrl + Shift +

选取该字符开始到该词开始的所有字符

Ctrl + Shift + [

选取该字符开始到与其匹配的左括号的所有字符

Ctrl + Shift + ]

选取字符开始到与其匹配的右括号的所有字符

Alt + Enter

将光标移到已选取文本的另一端

3)删除操作的快捷键

5-3所示为文本编辑器有关删除操作的快捷键。

5-3删除功能的快捷键

快捷键

功能

Ctrl + 退格

删除光标左边的词

Shift + 退格

删除光标右边的词

Ctrl + E,再单击E

删除从光标到行末的所有字符

4)代码缩排编辑快捷键

Visual LISP 按默认的格式缩排程序代码 , 可以通过下拉菜单 ToolsWindow AttributesConfigure Current选项设置制表符Tab的宽

度(缩进的字符数),也可以用表5-4所示代码缩排编辑的快捷键,还可

以自定义格式编排程序的选项(参见5.4设置代码格式)。

5-4代码缩排编辑快捷键

快捷键

功能

Tab

向后缩进Tab所确定的距离

Shift + Tab

向前减少缩进Tab所确定的距离

Shift + Enter

清除随后的空格键和 TAB 键,插入一个换行符,并 将该行缩排至和前一个非空行平齐。

Ctrl + Enter

插入一个换行符而不清除当前行中随后的空格键和

TAB 键。

5.2 文本操作

1. 选取文本

双击鼠标左键是选取文本最简单的方法,具体选取了哪些字

符是根据光标在以下的位置决定的。

1)若光标紧挨某左圆括号之前,将选取该左圆括号至与之匹

配的右圆括号之间的所有文本;

2)若光标紧跟某右圆括号之后,将选取该右圆括号至与之匹

配的左圆括号之间的所有文本;

3)若光标紧挨某双引号之前,将选取该双引号至下一个双引

号之间的所有文本;

4)若光标紧跟某双引号之后,将选取该双引号至前一个双引

号之间的所有文本;

5)若光标紧挨某字符串前、紧跟某字符串后或某字符串内部,

将选取该字符串。

单击鼠标左键,按住Shift键,在另一个位置单击鼠标左键,

将选取这两个光标之间的所有文本。

除了以上的方法之外,还可使用表5-2所示的文本选取快捷键。

2. 移动文本

除了使用标准的Windows剪切、复制和粘贴功能外,Visual LISP 文本编 辑器还允许用户用以下方法将文本从文本编辑器窗口的某个位置拖到另一个 位置。

移动文本的步骤是:(1)选取要移动的文本;(2)光标移到被选取文

本之内的任意位置后,按住鼠标左键,光标改变为图5-2(a)所示的形状。

3)将文本拖拽到新的位置,松开鼠标左键即可。

3. 复制文本

复制文本与移动文本只有第三步不同,在拖拽文本时,需要按住Ctrl键,

光标改变为图5-2(b)所示的形状,然后将文本复制到新位置。

所示的形状,然后将文本复制到新位置。 (a) (b) 图 5 - 2 用鼠标移动和复制文本时的光标

(a)

所示的形状,然后将文本复制到新位置。 (a) (b) 图 5 - 2 用鼠标移动和复制文本时的光标

(b)

5-2 用鼠标移动和复制文本时的光标

4. 查找文本

4. 查找文本 选择下拉菜单 S earch  F ind ,或单击工具栏按钮 ,将弹出图 5-3 所

选择下拉菜单SearchFind,或单击工具栏按钮 ,将弹出图5-3

示查找对话框。

,将弹出图 5-3 所 示查找对话框。 图 5-3 查找对话框

5-3查找对话框

有关查找文本对话框的说明如下:

1Find What编辑框:用于输入要查找的字符串,如果在查找操作前选

取了文本,被选文本将会自动出现在Find What文本框内。

2Search栏:确定查找范围。该栏有四个互锁按钮。依次是:

Current selection:在文本编辑器窗口中亮显的文本中查找;

Current file:仅在活动编辑器窗口中的文件中查找;

Project:在随后指定的工程文件所包含的全部文件中查找,并在新的输出窗

口中显示所有与查找字符串匹配的表达式。

Files:在指定要查找文件目录和文件类型的所有文件中查找,并在新的输出

窗口中显示所有与查找字符串匹配的表达式。在这个新的输出窗口用鼠标左键双击 任意亮显的表达式,Visual LISP将打开与其相关的LISP文件。文件的类型可以用通

配符。

3Direction栏:确定查找方向。该栏有两个互锁按钮。依次是:

Down:从光标当前位置处开始向下查找;

Up:从光标当前位置处开始向上查找。

4Match whole word only切换开关:如果为开,仅匹配全字。例如,若

查找的文本是entVisual LISP认为它不与entnext匹配;如果为关时, Visual LISP将认为ententnext匹配。

5Match case切换开关:如果为开,Visual LISP区分字母的大小写。例 如,若查找的文本是carVisual LISP认为它不与CarCAR匹配;如果为关 时,Visual LISP将认为carCARCar匹配。

6Mark instances切换开关:如果为开,将在每个找到的文本处加上书

签。利用书签就可以快速找到这些代码所在的位置。

点取Find按钮将开始查找。如果查找的范围是工程或文件目录,将在新 的输出窗口中显示所有与查找字符串匹配的表达式。如果是在单个文件或亮 显的段落中查找,将从光标当前位置处按指定方向开始查找,若找到与之匹 配的对象,就停止查找且亮显与之匹配的对象,同时光标移至该位置。若找

不到与之匹配的对象,将弹出要求用户确认是否从头查找的对话框。按F3

或按钮将从当前位置查找下一个相同的查找内容的字符串。

Visual LISP将每次输入的查找字符串都保存在工具栏的下

拉表列内,见图5-4。如果要重复以前所做的查找,单击下拉箭

头并从列表中选中要查找的项,然后从工具栏中选择查找按钮即

可。

可。 图 5-4 保存查找字符串的下拉列表

5-4保存查找字符串的下拉列表

5. 替换文本

选取Search下拉菜单的Replace选项,或点取工具栏的按钮

5-5所示替换对话框。

Replace 选项,或点取工具栏的按钮 5-5 所示 替换 对话框。 , 将弹出图 图 5-5 替换对话框

,将弹出图

Replace 选项,或点取工具栏的按钮 5-5 所示 替换 对话框。 , 将弹出图 图 5-5 替换对话框

5-5替换对话框

替换文本对话框与查找文本对话框类似,有关说明如下:

1Find what编辑框:输入要查找的字符串。

2Replace with编辑框:输入用来替换查找内容的字符串。

3Find按钮:从光标所在位置开始,按指定方向查找指定字符串的第一