版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第1章,AutoLISP和Visual LISP,1.1 關(guān)于LISP,LISP是人工智能領(lǐng)域中廣泛采用的一種程序設(shè)計語言。主要用于人工智,能、機(jī)器人、專家系統(tǒng)、博奕、定理證明等領(lǐng)域。,LISP也被稱為符號式語言,因為它處理的對象是符號表達(dá)式。LISP語言,的程序和數(shù)據(jù)都是以符號表達(dá)式的形式來表示,因此,一個LISP程序可以把,另一個LISP程序作為它的數(shù)據(jù)來處理。,LISP語言語法簡單,編寫程序便捷、靈活,數(shù)據(jù)類型豐富。利用LISP語
2、,言可以很容易地定義或調(diào)用新的函數(shù)。這就是Autodesk公司早在1985年的2.1,版本就引用了LISP語言的宏操作,在1986年的2.5版本就推出了比較完整的,AutoLISP語言的原因。,LISP在它幾十年的發(fā)展過程中產(chǎn)生了多種版本,如MacLISP、InterLISP,、ZetaLISP、和CommonLISP等。其中CommonLISP是近幾年美國的幾所大,學(xué)(如麻省理工、斯坦福等)和工業(yè)界(如Bell實驗室、DEC公司、HP
3、公司,等)的人工智能研究人員協(xié)同推出的,它概括了MacLISP、InterLISP、,ZetaLISP等版本的特點(diǎn),因而功能較強(qiáng)且擁有其它版本的一些優(yōu)點(diǎn),是目前,LISP語言較完整的版本。,1.2 關(guān)于AutoLISP,AutoLISP是為二次開發(fā)AutoCAD而專門設(shè)計的編程語言,它起源于LISP,語言,嵌入在AutoCAD的內(nèi)部,是LISP語言和AutoCAD有機(jī)結(jié)合的產(chǎn)物。,AutoLISP 采 用 了 和 CommonLISP
4、最 相 近 的 語 法 和 習(xí) 慣 約 定 , 具 有,CommonLISP的特性,但又針對AutoCAD增加了許多功能。它既有LISP語言,人工智能的特性,又具有AutoCAD強(qiáng)大的圖形編輯功能的特點(diǎn)。它可以把,AutoLISP程序和AutoCAD的繪圖命令透明地結(jié)合起來,使設(shè)計和繪圖完全融,為一體,還可以實現(xiàn)對AutoCAD圖形數(shù)據(jù)庫的直接訪問和修改。,利用AutoLISP語言可以進(jìn)行各種工程分析計算、自動繪制復(fù)雜的圖形,,還可以定
5、義新的AutoCAD命令、驅(qū)動對話框、控制菜單。為AutoCAD擴(kuò)充具,有一定智能化、參數(shù)化的功能,可以使設(shè)計人員的主要精力用于產(chǎn)品的構(gòu)思,和創(chuàng)新設(shè)計上,實現(xiàn)真正意義上的計算機(jī)輔助設(shè)計。,1.3 關(guān)于Visual LISP,Visual LISP是Autodesk公司在1997年14版本推出的。它是為,加速AutoLISP程序開發(fā)而設(shè)計的軟件開發(fā)工具,是一個完整的,集成開發(fā)環(huán)境。 Visual LISP包括文本編輯器、格式編排器、語,
6、法檢查器、源代碼調(diào)試器、檢驗和監(jiān)視工具、文件編譯器、工,程管理系統(tǒng)、上下文相關(guān)幫助與自動匹配功能和智能化控制臺,等。,Visual LISP用戶界面良好,用過Microsoft軟件的用戶只需很,短的時間即可掌握它。,Visual LISP兼容以前的AutoLISP程序。在Visual LISP集成環(huán),境下開發(fā)AutoLISP程序,就不再象以前那樣編輯程序時,用其,它系統(tǒng)的文本編輯程序編寫程序代碼;調(diào)試程序時,需要用戶,自己決定在程
7、序的什么位置插入打印語句,以便查看變量的內(nèi),容;在程序運(yùn)行正常后,再將插入的調(diào)試代碼刪除或注釋掉。,在VLISP集成環(huán)境下可以便捷、高效地開發(fā)AutoLISP程序,,可以經(jīng)過編譯得到運(yùn)行效率更高、代碼更加緊湊、源代碼受到,保護(hù)的應(yīng)用程序。,Visual LISP是新一代AutoLISP語言,它對AutoLISP語言進(jìn)行,了 擴(kuò) 展 , 可 以 通 過 Microsoft ActiveX Automation 接 口 與,AutoCA
8、D對象交互,可以通過反應(yīng)器函數(shù)擴(kuò)展AutoLISP響應(yīng)事,件的能力。,如果使用Visual LISP對AutoLISP擴(kuò)展功能的部份,必須調(diào)用,vl-load-com 函 數(shù) , 或 者 將 調(diào) 用 該 函 數(shù) 的 表 達(dá) 式 寫 在,acad2006doc.lsp 文件內(nèi)。,第2章,數(shù)據(jù)類型、表達(dá)式和函數(shù),AutoLISP的數(shù)據(jù)類型豐富,除了一般程序設(shè)計語言具有的整,型、實型、字符串等類型之外,還有表、函數(shù)、文件描述符、,AutoCA
9、D選擇集、AutoCAD圖元名、VLA對象、函數(shù)分頁表和,外部函數(shù)等數(shù)據(jù)類型。,2.1 數(shù)據(jù)類型,1. 整型(INT),整型即整數(shù),整數(shù)由數(shù)字和正負(fù)號組成,正號可省略。整數(shù)為,32位帶符號的數(shù)字,其范圍從-2147483648到+2147483647。,2. 實型(REAL),實型數(shù)是帶小數(shù)點(diǎn)的數(shù)。在-1和1之間的實數(shù)必須以0開頭,例,如:.5是錯誤的,應(yīng)該寫成0.5。實數(shù)用雙精度的浮點(diǎn)數(shù)表示,并,且至少有14位有效位數(shù)的精度。注意,V
10、isual LISP不顯示所有的,有效位。,3. 字符串(STR),字符串又被稱為字符常數(shù),它是由雙引號括起來的字符序列,。字符串中字母的大、小寫和空格符都是有意義的。,字符串中字符的個數(shù)(不包括雙引號)稱為字符串的長度。字,符串的最大長度為100,如果超過100,第100個字符后面的字符,將是無效的。字符串可以是空的,即"",稱為空串,其長度為0,。,任何字符都可以用\nnn的格式表示,其中反斜杠“\”是ASCI
11、I碼,的前導(dǎo)標(biāo)識字符,nnn是該字符八進(jìn)制的ASCII碼。例如,字符,串ABCD也可表示為\101\102\123\104。一些常用的控制字符,象,反斜杠、雙引號,除了可以用 \nnn的格式表示之外,還可以用,“\”轉(zhuǎn)義字符的格式表示為“\\”、“\"”等特殊字符,見下表。,,,,,,,,,,,表2-1常用控制字符的表示方法,控制字符反斜杠“\”雙引號“"”Esc鍵換行回車鍵Ta
12、b鍵,用“\”為前導(dǎo)字符\\\"\e\n\r\t,用“\”為前導(dǎo)的ASCII碼表示\134\042\033\012\015\011,注意,其中的字符e,n,r,t必須小寫。,4. 表,表以左圓括號開始,以配對的右圓括號結(jié)束,表可以是空的,,可以有若干個元素;元素可以是簡單的,也可以是復(fù)雜的,,還可以是其它的表。例如:(+ 1
13、 2 3)、(sin (* 0.5 pi)),、(A B)、((A B) C (C D))、(0 "LINE")、(101.5 2.6 0.0)、()都是合法的表。表中元素的個數(shù)稱為表的長度。例如,表(+ 1 2 3)的長度為4、表(sin (* 0.5 pi))的長度為2、表((A B) C (C D))的長度為3、表()的長度為0。用表可以方便地構(gòu)造出復(fù)雜的數(shù)據(jù)結(jié)構(gòu),例如
14、,(1.5 3.6)可以表示為一個X等于1.5、Y等于3.6的二維點(diǎn),(2.5 2.0 1.0)可以表示為一個X等于2.5、Y等于2.0、Z等于1.0的三維點(diǎn)。,5. 函數(shù)(SUBS),函數(shù)相當(dāng)于子程序或過程。函數(shù)分為內(nèi)部函數(shù)和外部函數(shù)。AutoLISP提供的或用AutoLISP定義的函數(shù)為內(nèi)部函數(shù)。用ADS、ADSRX或ARX定義的函數(shù)為外部函數(shù)。例如sin 、cos、sqrt為內(nèi)部函數(shù)。,運(yùn)算符在AutoLI
15、SP里屬于函數(shù),例如“+”、“-”、“*”、,“/”分別稱之為加、減、乘、除函數(shù),“”分別稱之為小于、小于等于和大于函數(shù)。,其它計算機(jī)語言里的子程序、過程、程序流程控制的關(guān)字,在AutoLISP里也屬于函數(shù),例如“if”、 “while”分別稱之為條件和條件循環(huán)函數(shù)。,6. 文件描述符(FILE),文件描述符是AutoLISP賦于被打開文件的標(biāo)識號,它類似于,文件指針。下面的例子是以“讀”的方式打開文件myfile.dat,
16、并,將該文件的描述符賦予符號f1。,(setq f1 (open "myfile.dat" "r")) 返回,7. 圖元名(ENAME),圖元名是AutoCAD為圖形對象指定的16進(jìn)制的數(shù)字標(biāo)識。AutoLISP通過該標(biāo)識,找到該圖形對象在圖形數(shù)據(jù)庫中的位,置,以便對其進(jìn)行訪問或編輯。,8. 選擇集(PICKSET),選擇集是一個或多個圖形對象命名的集合??梢酝ㄟ^,AutoLISP程序建立
17、選擇集、向指定的選擇集添加或移去圖形對,象,通過選擇集可以對其內(nèi)指定的成員進(jìn)行訪問或編輯。,9. VLA 對象,VLA 對象是ActiveX 應(yīng)用程序的主要組成部分。 不僅直線,、圓弧、多義線和圓等都被稱為VLA對象,圖層、組、塊、視,圖、視口、圖形的模型空間、圖紙空間、線型和尺寸標(biāo)注樣式,等也被稱為VLA對象,甚至連AutoCAD本身也被認(rèn)為是VLA對,象。,2.2 變量,2.2.1 符號,符號(SYMBOL)可以理解為標(biāo)識,用來作為
18、變量、函數(shù)的名字。它的命名規(guī)則是不能只含數(shù)字,可以由下列字符以外的任何可打印的字符所組成:,“(”、“)”、“·”、“'”、“"”、“;”,例如,a1、b2 、c_3是合法的符號,(a、)b、.c、’4、"5是非法的符號。注意:[1]、{2}、~3、!4、/5、1a、3c、-d、+e、b-2、c*3也是合法的符號,這是與多數(shù)計算機(jī)語言的不同之處。,在AutoLISP中,符號的大
19、小寫等價,符號的長,度沒有限制,且所有的字符都是有意義的。,如果一個符號的長度不超過6,就用節(jié)點(diǎn)本身來存,儲;如果符號的長度超過6,這樣的符號就不能用節(jié),點(diǎn)來存儲,而是在節(jié)點(diǎn)中存放一個指向?qū)嶋H存儲符號,名的指針。這將會多占用存儲空間,且減慢了執(zhí)行速度。因此,符號的長度最好不要超過6。,2.2.2 變量的數(shù)據(jù)類型,AutoLISP變量屬于符號,是指存儲靜態(tài)數(shù)據(jù)的符號。,數(shù)據(jù)類型是變量的重要的特征,因為它關(guān)系到存放變量值的,存儲空間的
20、大小。多數(shù)的計算機(jī)語言都在為變量賦值前對變量做顯式或隱式的說明。AutoLISP無須對變量做事先的類型說明,,變量被賦予值的類型即為變量的類型。,用setq函數(shù)對變量賦值,例如,(setq a 5),賦值后的結(jié)果是:變量a是整型的,因為5是整型的;同樣的原因,(setq b 2.5)之后, b是實型的,(setq c "ABC")之后,c就是字符串類型的。,在程序運(yùn)行過程中,同一變量在不同的時
21、刻可以被賦予不同類型的值,因此在程序運(yùn)行過程中,變量的數(shù)據(jù)類型是可以被改變的。,例如,在一個程序里有以下兩行:,(setq a 5)當(dāng)前的變量a是整型的。,(setq a "ABC") 當(dāng)前的變量a是字符串類型的。,用type函數(shù)了解變量的類型,例如,(type a ) 返回INT,顯示變量a是整型的;(type b)返回REAL,顯示變量b是實型的,(type c) 返回STR,顯示變量c是字
22、符串類型的。,2.2.3 為變量賦值,用setq函數(shù)為變量賦值,其格式如下:(setq 變量1 值1[變量2 值2 . . .]) 例如:Command:(setq x 1.5 y 20 p "Center")返回“Center”除了為變量x、y、p賦值外,還返回最后一個表達(dá)式的結(jié)果,“Center”。如果上述表達(dá)式還有外層表達(dá)式,那么,將把該表,達(dá)式的返回值“Center”賦給外層表達(dá)式的
23、變量。例如,,Command:(setq v(setq x 1.5 y 20 p "Center") )返回“Center”該表達(dá)式同樣為變量x、y、p賦值,并將內(nèi)層表達(dá)式返回的結(jié),果“Center”賦給變量v,最后返回外層表達(dá)式的結(jié)果“Center”。,沒有被賦值的變量屬于無定義的變量。,2.2.4 預(yù)定義的符號,AutoLISP對變量nil、T、Pause和Pi進(jìn)行了預(yù)定義,用戶可以,在編寫Auto
24、LISP程序時直接使用。,(1) nil,如果變量沒有被賦值,它的值為nil。nil與空和0不同的是,它,既不是空串,也不是0值,它表示尚無定義。引用未被賦值的變,量是錯誤的。例如,變量x尚未被賦值,(+ 1 x)就會出現(xiàn)error:,bad argument type(壞的參數(shù)類型錯)。,將nil賦給某一有定義的變量,其結(jié)果是:取消該變量的定義,,并釋放其所占存儲空間。,nil作為邏輯變量的值,表示不成立,相當(dāng)于其他程序設(shè)計語,言的f
25、alse。,(2)T,T為常量,它作為邏輯變量的值,表示成立,相當(dāng)于其他程,序設(shè)計語言的true。,(3)PAUSE,PAUSE與command函數(shù)配合使用,用于暫停,等候用戶輸,入。,(4)PI,PI被定義為常量 π。每個變量都占用一些內(nèi)存空間。為了節(jié)省存儲空間,可重復(fù),使用變量名,或者將不再使用的變量設(shè)為nil,以便釋放該變量,所占的內(nèi)存空間。,必須注意,一般的編程語言不允許將內(nèi)部函數(shù)名或,流程控制的關(guān)鍵字作為變量名,而Aut
26、oLISP沒有這,樣的限制。因此,程序中定義的符號名稱不要與系統(tǒng),定義的函數(shù)名和預(yù)定義的變量名相同,否則,后面的,定義將取代已有的定義,從而引起混亂。例如,sin是,正弦函數(shù),可是在執(zhí)行表達(dá)式(setq sin 1)之后,sin,不再是正弦函數(shù),而是一個值為1的整型變量。,2.2.5 顯示變量的值,要想在AutoCAD命令提示區(qū)顯示變量的值,必須在變量名前添加驚嘆號!。例如了解前面已賦值的變量x、v的值,操作如下:,Comman
27、d:!x,1.5,Command:!v,"Center",Command:!z,nil(假定變量z尚未被定義),R,2.2.6 在交互方式下將變量的值傳遞給AutoCAD,在變量前加一個感嘆號 “ ! ” ,即可將表達(dá)式的值傳遞給,AutoCAD。例如:,Command:(setq p '(20 10) r 5)Command:circleSpecify center point fo
28、r circle or [3P/2P/Ttr(tan tan radius)]:,!p,Specify radius of circle or [Diameter]::!r即可畫出圓心的坐標(biāo)為(20,10)半徑為5的圓。,2.3 表達(dá)式,AutoLISP處理的對象是符號表達(dá)式(簡稱表達(dá)式)。表達(dá)式相,當(dāng)于其他編程語言中程序的語句。,2.3.1 表達(dá)式的構(gòu)成,表達(dá)式是由原子或表構(gòu)成的。原子可細(xì)分為數(shù)原子、串原子和,符號原子。數(shù)或串原
29、子的值是數(shù)或串本身,符號原子的值是賦給,該符號的值。例如:5、12.5、“ABC"是單個原子構(gòu)成的表達(dá)式。,多數(shù)情況下,表達(dá)式以表的形式存在,其格式如下:(函數(shù)名 [變元]…)變元的數(shù)量可能為0,也可能任意多個,這取決于具體函數(shù)。每,個參數(shù)還可以是一個表達(dá)式。,表達(dá)式形式的表,左圓括號之后的第一個元素必須是函數(shù)名。,2.3.2 表達(dá)式的前綴表示法,大多數(shù)計算機(jī)語言的表達(dá)式采用中綴表示法,即運(yùn)算符在操,作數(shù)中間。如,x
30、=2.5,y=1+2。,AutoLISP采用前綴表示法,將函數(shù)名放在所有操作數(shù)之前。,如,(setq x 2.5),(setq y(+ 1 2))。,若將x=(a+b)*c 改寫為AutoLISP表達(dá)式,則為:(setq x(* (+ a b) c))前綴表示法使得運(yùn)算和函數(shù)調(diào)用的形式得到了統(tǒng)一。前面提,到,在AutoLISP語言里,運(yùn)算符也屬于函數(shù)。,2.3.3 表達(dá)式的求值過程,在LISP語言中,函數(shù)之間不存在是
31、否優(yōu)先的關(guān)系,運(yùn)算的先后順序只能通過表的層次來實現(xiàn),最里層的表最先被求值,把求值的結(jié)果返回給外層表,直至求值完畢。,例如,表達(dá)式(setq x(* (+ a b) c)),先求出最內(nèi)層a與b之和,然后求出a、b之和與 c的積,將求得的積賦給x,最后返回x的值。,可以在Command:提示下,輸入一個表達(dá)式,AutoCAD將計算該表達(dá)式并返回計算結(jié)果。AutoCAD至多顯示6位小數(shù)。,例如,在Command:提示下,鍵
32、入(sin 0.5)之后回車,將,返回0.479426。,如果輸入的或者從文件中讀入的表達(dá)式不正確,將顯示出錯信,息,最常見的出錯信息是:,(((_>,表示缺少與左圓括號匹配的右圓括號,“(”的個數(shù)即為缺少右,圓括號的數(shù)量。如果出現(xiàn)該信息,輸入與所提示的左圓括號相等,的右圓括號既可。由于所缺的右圓括號不一定都是最后的,所以,可能產(chǎn)生錯誤的結(jié)果。,如果遺漏了與左端雙引號匹配的右端的雙引號,顯示的出錯信,息為:,("_>
33、;在這種情況下輸入匹配的雙引號也不一定使表達(dá)式能正常求值,。此時只能按Esc鍵終止當(dāng)前的輸入,重新輸入表達(dá)式。,2.3.4 表達(dá)式的求值規(guī)則,(1)整型數(shù)、實型數(shù)、字符串,以它們本身的值作為求值結(jié),果。,(2)符號以它們當(dāng)前的約束值作為求值結(jié)果。(3)表是根據(jù)其第一個元素來進(jìn)行求值的。① 如果第一個元素或第一個元素的計算結(jié)果是一個函數(shù)名,,那么以表中剩余的元素作為該函數(shù)的變元,計算出該函數(shù)的值,。例如,表達(dá)式:,(+ (
34、* 2 3) (/ 50 3))先計算最內(nèi)層的表達(dá)式(* 2 3)和 (/ 50 3),將結(jié)果6和16,返回給其外層表達(dá)式,原表達(dá)式變?yōu)椋海? 6 16),繼續(xù)計算表達(dá)式(+ 6 16),返回22。,② 如果第一個元素是一個表,該表不是調(diào)用而是定義函數(shù),,若語法正確,首先定義這個函數(shù),然后繼續(xù)表達(dá)式求值。,③ 如果第一個元素既不是函數(shù)名,也不是定義函數(shù),將停,止求值并顯示出錯信息。,例如(25 a b c),將停止求值并顯示
35、“error: bad function:,25”,因為25是非法的函數(shù)名,所以顯示25是壞函數(shù)的出錯信,息。,又比如(fx a b c) ,將停止求值并顯示“error: no function,definition: FX” ,指出沒有定義fx這個函數(shù)。,④ 用quote函數(shù)可以禁止對表求值。對于不需求值而直接整體引用的表,例如將一個表示三維點(diǎn),的表(3 2 1)賦給變量p,如果表達(dá)式為(setq p(3 2 1
36、)),,將中斷求值過程并顯示“error: bad function: 3”出錯信息。因,為首先對內(nèi)層表求值,而內(nèi)層表的第1個元素“3”不是函數(shù)名,,所以停止求值。此時應(yīng)該用quote函數(shù),將表達(dá)式改為(setq p,(quote(3 2 1))),這樣就不再對表(3 2 1)求值,而是,將將表(3 2 1)整體賦給變量p,使之表示一個3維的點(diǎn)。,quote是AutoLISP程序中使用最多的函數(shù),因此該函數(shù)可用,一個單引號“
37、39;”表示。例如(quote (10 20))可以表示為'(10 20),。如果將(10 20)這個2維點(diǎn)賦給變量p2,可寫成:,(setq p2 '(10 20)),2.4 數(shù)據(jù)的存儲結(jié)構(gòu),計算機(jī)的內(nèi)存是由許多編了碼的內(nèi)存單元組成。一個特定內(nèi),存單元的編號稱為內(nèi)存地址。內(nèi)存單元的內(nèi)容是數(shù)字,也可以是,內(nèi)存單元的編號,即另一內(nèi)存單元的地址。如果一個內(nèi)存單元的,內(nèi)容是另一個內(nèi)存單元的地址,那么,這個內(nèi)存單元被稱為是指
38、,向另一個內(nèi)存單元的指針。如果一個內(nèi)存單元分為左、右兩部分,,分別存放兩個內(nèi)存單元的地址,那么,這個內(nèi)存單元就具有左,、右兩個指針。,這種具有左、右兩個指針的內(nèi)存單元被稱為節(jié)點(diǎn)。每個節(jié)點(diǎn),的長度是12個字節(jié),等分為左、右兩部分,作為左、右指針,每,個節(jié)點(diǎn)都有它的地址。AutoLISP通過這樣的一些節(jié)點(diǎn)構(gòu)成鏈表,,以鏈?zhǔn)椒绞酱鎯Ω鞣N數(shù)據(jù)。,1. 符號,創(chuàng)建一個符號,例如(setq radius 10),至少需要3個節(jié)點(diǎn)。,一個節(jié)點(diǎn)
39、鏈接到符號原子表的鏈尾并指向存放符號名的節(jié)點(diǎn),,一個節(jié)點(diǎn)存放符號名和存放符號值的指針,最后一個節(jié)點(diǎn)存放,符號的值,見圖(a)。,如果符號的長度超過6字符,例如(setq fillet_radius 5),需,要申請存放符號名的存儲空間,用原來存放符號名的半個節(jié)點(diǎn),作為指向存放符號名的指針,見圖(b)。顯然要多占用一些存儲,空間。,2. 字符串,字符串在內(nèi)存中是以連續(xù)的空間存儲的。,3. 表,表通過一組節(jié)點(diǎn)來存儲。這些節(jié)點(diǎn)用右指針
40、指向各自下一個元,素的地址,最后一個節(jié)點(diǎn)的右指針為空,用左指針指向各自的元,素。,下圖依次是表(A B C D)、(A (B C)(D E)) 和(setq x(,+ (* ab)(/ cd)))的存儲結(jié)構(gòu)。,4. 點(diǎn)對(dotted pair),點(diǎn)對是一種特殊的表。若表只有兩個元素,且每個元素都是原子,這樣的表可以用點(diǎn)對表示。點(diǎn)對的形式為(原子 . 原子),如(0 . "LINE")、(8 . &quo
41、t;A1")、(40 . 15.0)。用一個結(jié)點(diǎn)存放點(diǎn)對,結(jié)點(diǎn)的左指針指向第一個元素,右指針指向第二個元素。圖是只有兩個元素(元素為原子)的表的存儲結(jié)構(gòu),圖(b)是點(diǎn)對的存儲結(jié)構(gòu)。從圖中不難得出結(jié)論,兩個元素都是原子的表,用點(diǎn)對會節(jié)省存儲空間。點(diǎn)對的另一個特點(diǎn)是簡化了某些函數(shù)對表的運(yùn)算。由于點(diǎn)對具有這些優(yōu)點(diǎn),因此是,AutoLISP常用的數(shù)據(jù)結(jié)構(gòu)。,2.5 函數(shù),前面提到,一般計算機(jī)語言所說的函數(shù),AutoLIS
42、P照常稱之為,函數(shù);一般計算機(jī)語言里的子程序、過程、運(yùn)算符、程序流程控,制的關(guān)鍵字,在AutoLISP里都被稱之為函數(shù)。,AutoLISP將函數(shù)分為內(nèi)部和外部函數(shù)。AutoLISP提供的或用,AutoLISP定義的函數(shù)為內(nèi)部函數(shù)。用ADS、ADSRX或ARX定義,的函數(shù)為外部函數(shù)。,2.5.1 定義AutoLISP函數(shù),定義函數(shù)用defun函數(shù)。格式如下:,(defun 函數(shù)名 (變元... / 局部變量... ) 表達(dá)式 ...),函
43、數(shù)名:函數(shù)名和變量名的命名規(guī)則相同,是代表一個函數(shù)的,符號,不應(yīng)與現(xiàn)有的AutoLISP函數(shù)同名,否則現(xiàn)有函數(shù)的功能被,新定義函數(shù)的功能所取代。,變元:變元即該函數(shù)的參數(shù),變元的數(shù)量根據(jù)實際需要而定,,可以沒有變元,但不能省略一對括號“()”。,局部變量:在定義函數(shù)時,除了用到函數(shù)的參數(shù)之外,還可能,用到其他一些變量。在該域列舉這些變量的名字,這些變量就,成為局部變量。局部變量是指局限于該函數(shù)內(nèi)部所用的變量,,它只在該函數(shù)調(diào)用期間得到定
44、義,函數(shù)調(diào)用結(jié)束,局部變量的,值均為nil,同時釋放其所占存儲空間。如果不作聲明,它們將,成為全程變量,即使函數(shù)調(diào)用結(jié)束,仍然保留各自的值,可被,其他函數(shù)所存取,直至退出當(dāng)前的圖形文件。進(jìn)行局部變量聲,明不僅可以節(jié)省存儲空間,而且可以避免函數(shù)之間相互干擾。,局部變量與變元之間用除號隔開,即使沒有變元,也可以有局,部變量說明,但前面要有除號。,表達(dá)式:表達(dá)式的數(shù)量不限,用于描述該函數(shù)的運(yùn)算。函數(shù)的返回值:最后一個表達(dá)式的返回值即為
45、該函數(shù)的返回,值。,【例2-1】定義一個加10函數(shù),源代碼如下:,(defun add10(x),(setq x(+ 10 x)),),或者:,(defun add10(x),(+ 10 x),),該函數(shù)的函數(shù)名是add10,只有一個變元x,沒有局部變量說,明,它返回表達(dá)式(setq x(+ 10 x))或(+ 10 x)的值(二者是相等,的)。,v(*,【例2-2】定義一個已知圓柱體的半徑和高度,計算其,體積的函數(shù)。源代碼如下:
46、,(defun volume(r h / v),(setq v(* r r pi h)),),該函數(shù)的函數(shù)名是volume ,有兩個變元r(半徑)和h(高度),有一個局部變量v,它返回表達(dá)式(setq,r r pi h))的值。,2.5.2 調(diào)用AutoLISP函數(shù),AutoLISP以表的形式調(diào)用函數(shù),其格式如下:(函數(shù)名 [變元]…)表的第一個元素是函數(shù)名,其余是該函數(shù)所要求的變元,變元的,數(shù)量可能為0,也可能
47、任意多個,這取決于具體函數(shù)。例如,,(sqrt 4),調(diào)用的函數(shù)名為sqrt(求平方根),函數(shù)的變元是4,、只有一個變元;,(+ 1 2 3),調(diào)用的函數(shù)名為“+”(加),函數(shù)的變元是1、2、,3,共有3個變元。,每個變元還可以是一個表達(dá)式。例如:(sqrt (+ 1 2 3))。,每調(diào)用一個函數(shù),都會得到函數(shù)的返回值。例如,,(sqrt 4) , 返回2(+ 1 2 3) , 返回6,有些函數(shù)返回邏輯常數(shù)T或nil,例如,
48、,(< 1 2), 返回T;,(not 1),返回nil。,調(diào)用自定義的函數(shù)與調(diào)用系統(tǒng)提供的函數(shù)的格式相同。例如,,(add10 3),(setq y(add10 (+ 2 3))),(volume 12.5 20)1),2.5.3 遞歸調(diào)用AutoLISP函數(shù),AutoLISP可以在一個函數(shù)的內(nèi)部定義另一個函數(shù),可以遞歸,定義和調(diào)用函數(shù)。,【例2-3】定義階乘函數(shù),階乘的定義是,0的階乘等于1,n的階乘等于n×(n
49、-1)的階,乘。程序的源代碼如下:,(defun factorial(x)(if (= x 0)1(* x (factorial (- x 1))))),2.5.4 調(diào)用AutoCAD命令,AutoLISP用command函數(shù)調(diào)用AutoCAD命令,其格式如下:,(command “AutoCAD命令” "命令所需的數(shù)據(jù)" …),【例2-4】繪制以(2,4)為
50、圓心,5為半徑的圓。,(command "circle" "2,4" 5)或者,(command "circle" ‘(2 4) 5),【例2-5】已知p1、p2、p3為不在同一直線上的三個點(diǎn),利用這,三個點(diǎn)畫圓。,(command "circle" "3p" p1 p2 p3),【例2-6】畫從點(diǎn)p1(0,0)到點(diǎn)p2(10,0)
51、的一段直線。,(command "line“ "0,0“ "10,0“ "")或者,(command "line" '(0 0) '(10 0) "")或者,(command "line" (list 0 0) (list 10 0) "")或者,(comman
52、d "line“ p1 p2 "");假定p1、p2是兩個點(diǎn),注意:因為繪制直線時用空回車或空格響應(yīng) “Specify next point,or [Undo]:”提示才能結(jié)束line命令,所以在最后一個點(diǎn)的后面要,增加兩個雙引號,代表一個回車或空格。,2.5.5 定義AutoCAD命令,定義AutoCAD命令用defun函數(shù)。格式如下:(defun C:AutoCAD命令名 (/
53、 局部變量... )表達(dá)式 ...)定義AutoCAD命令與定義函數(shù)基本相同,不同之處是,:,① 命令名前加“C:”。② 沒有變元,但可以有局部變量說明。此外要注意所定義的AutoCAD命令不應(yīng)與現(xiàn)有的,AutoCAD命令同名。,,【例2-7】定義輸入矩形的對角點(diǎn)繪制矩形的命令。,源代碼如下:,(defun c:rect1( / p1 p2 p3 p4) ;p1、p2、p3、p4是局部變元,(setq p1 (getp
54、oint "\n輸入矩形的一個角點(diǎn)" ))(setq p3 (getcorner p1 "\n輸入矩形的另一個角點(diǎn):" )),(setq p2(list (car p3) (cadr p1)))(setq p4(list (car p1)(cadr p3)))(command "pline" p1 p2 p3 p4 "c"),p4,p3,
55、),p1,p2,加載含有以上代碼的程序后,在AutoCAD的Command:命令,提示下,象調(diào)用普通命令一樣鍵入rect1,即可調(diào)用自定義的繪,制矩形的命令(見下圖)。,第3章,程序的流程控制和,AutoLISP文件,3.1 程序的流程控制,AutoLISP程序的流程通過流程控制函數(shù)控制。,3.1.1 分支結(jié)構(gòu),1. (cond (測試表達(dá)式1 結(jié)果表達(dá)式1) [(測試表達(dá)式2 結(jié)果表達(dá)式2)] …),該函數(shù)從第一個子表起,計算每
56、一個子表的測試表達(dá)式,直至有一個子表的測試表達(dá)式成立為止,然后計算該子表的結(jié)果表達(dá)式,并返回這個結(jié)果表達(dá)式的值。,例如,當(dāng) i 小于等于1時,n=1;小于等于2時,n=4;小于等于3時,n=10;其它情況下n=100。用cond函數(shù)實現(xiàn)變量n和i 之間以上關(guān)系的源代碼如下:,成立,測試表達(dá)式1不成立成立測試表達(dá)式2不成立成立測試表達(dá)式n不成立,結(jié)果表達(dá)式1
57、結(jié)果表達(dá)式2結(jié)果表達(dá)式n,成立,測試表達(dá)式1不成立成立測試表達(dá)式2不成立成立測試表達(dá)式n不成立T(其余),結(jié)果表達(dá)式1結(jié)果表達(dá)式2結(jié)果表達(dá)式n結(jié)果表達(dá)式,(setq n(cond ((<= i 1) 1),((<= i 2) 4)((<= i 3) 10),(t
58、 100),)),說明:該函數(shù)類似于C語言的switch語句, 最后一個測試表達(dá)式“t(或T)”相當(dāng)于C語言的“default”,指其余的情況,例如i 等于5時,n等于100,也可以缺少這個測試表達(dá)式。與C語言switch語句不同的是,若某一測試表達(dá)式成立,即返回相應(yīng)結(jié)果表達(dá)式的值,不再向下測試。例如,上述表達(dá)式中,若i 等于0,已滿足第一個測試表達(dá)式(<= i 1),返回結(jié)果表達(dá)式的1,最后結(jié)果是n等
59、于1,運(yùn)算結(jié)束。,2.(if 測試條件表達(dá)式 表達(dá)式1 [表達(dá)式2]),若測試條件表達(dá)式結(jié)果為真,執(zhí)行表達(dá)式1,否則,執(zhí)行表達(dá),式2。例如:,(if (> a 1) (setq b 2) ),該表達(dá)式的含義是;如果a 大于 1,則b等于2,否則不作任何,計算,求值結(jié)束。,(if (> a 1) (setq b 2) (setq b 3) ),該表達(dá)式的含義是;如果a 大于 1,則b等于2,否則b等于3,,求值結(jié)束
60、。,注意:該函數(shù)最多只有3個變元,即測試條件表達(dá)式、表達(dá)式1和,表達(dá)式2。先分析下列程序代碼:,測試條件表達(dá)式,測試條件表達(dá)式,成立表達(dá)式1,成立表達(dá)式1,不成立表達(dá)式2,(if (> a 1),(setq b 2)(print (+ b a))(setq b 4)(print b),),該程序段的本意是,若條件成立,b等于2,然后打印a與b之,和,否則b等于4,然后打印b。但是
61、在執(zhí)行該程序段時,首先檢,查if函數(shù)變元的數(shù)量,第1個變元是測試條件表達(dá)式,它對應(yīng)表達(dá),式(> a 1),第2個變元是條件成立時執(zhí)行的表達(dá)式,它對應(yīng)表達(dá),式(setq b 2),第3個變元是條件不成立時執(zhí)行的表達(dá)式,它對應(yīng),表達(dá)式(print (+ b a)) ,那么后面的兩個表達(dá)式就是多余的變元,,因此顯示“too many arguments(變元太多)”的出錯信息。,若將該程序段改寫為以下代碼:,(if (&
62、gt; a 1),((setq b 2)(print (+ b a)))((setq b 4)(print b)),),用括號將條件成立或不成立的多個表達(dá)式括起,雖然變元的,數(shù)量改為3個,但會出現(xiàn)“error: bad function: 2”的出錯信息。原,因是在計算條件成立的表達(dá)式時,首先計算內(nèi)層表(setq b 2),,將其返回值“2”作為外層表的函數(shù)名,顯然這是一個壞的函數(shù)名,。利
63、用progn函數(shù)可以很好地解決了本程序段存在的問題。,3. (prong 表達(dá)式...),該函數(shù)將n個表達(dá)式組合起來,作為if函數(shù)的一個表達(dá)式。在執(zhí)行時,按順序計算n個表達(dá)式,返回最后一個表達(dá)式的計算結(jié)果,。例如:,(if (> a 1),(progn (setq b 2)(print (+ b a)))(progn (setq b 4)(print b)),),該程序段的執(zhí)行過程是,若條件成
64、立,b等于2,然后打印a與,b之和,返回a與b之和;若條件不成立,b等于4,然后打印4,返回4。,3.1.2 循環(huán)結(jié)構(gòu),1. (repeat 整數(shù)n 表達(dá)式 …),重復(fù)執(zhí)行n次,對所有的表達(dá)式求值,返回最后一個表達(dá)式的,計算結(jié)果。例如:,(setq a 1 b 100),(repeat 10,(setq a(1+ a))其它表達(dá)式 …(setq b(+ 10 b)),),執(zhí)行結(jié)果:a等于11,b等于200,返回值為2
65、00。,2. (while 測試式 表達(dá)式 …),若測試結(jié)果不為nil,執(zhí)行各表達(dá)式, 直至測試結(jié)果為nil。例如:,(setq i 1 a 10),(while (<= i 10),(setq a(+ a 10))其它表達(dá)式 …(setq i (1+ i ),),執(zhí)行結(jié)果:i等于11,a等于110,返回值為11。,例如,定義求解百錢買百雞的函數(shù)。題目是若母雞每只3個錢,,公雞每只2個錢,小雞每只0.5個錢。用10
66、0個錢買100只雞,有,幾個答案,每個答案各有幾只母雞、公雞和小雞(不包括0只),,打印所求的結(jié)果。,該例沒有合適的計算公式,只能利用枚舉,試出合適的結(jié)果,。首先分析母雞數(shù)量的范圍,如果母雞等于20,剩余40個錢。用,剩下的錢至少買1只公雞之后,可以買76只小雞,但雞的總數(shù)為,97(小于100),所以母雞的數(shù)量應(yīng)小于20。同樣,買了至少1只,母雞和32只公雞之后,剩余的33個錢最多買66小雞,雞的總數(shù)為,99(小于100),所以公雞的數(shù)
67、量應(yīng)小于32。小雞的數(shù)量只能是,100減去母雞與公雞之和。當(dāng)公雞的數(shù)量和錢數(shù)都等于100時,打,印這組解。,,,,【例3-1】解百錢買百雞程序,(defun chicken( / hen cock chick cost),(setq hen 1)(while (< hen 20);母雞的數(shù)量不超過20(setq cock 1)(while (< cock 32);公雞的可能數(shù)量不超過32
68、(setq chick (- 100 hen cock));小雞的數(shù)量(setq cost (+ (* 3 hen)(* 2 cock)(* 0.5 chick)));3種雞的錢數(shù)(if (= cost 100)(print (list "母雞=" hen " 公雞=" cock " 小雞=" chic
69、k)))(setq cock (1+ cock));公雞的數(shù)量加1)(setq hen (1+ hen)) ;母雞的數(shù)量加1),(princ);靜默退出,),說明:,① 程序的第3行(setq hen 1)不可缺少,否則第4行(while (< hen 20),中的hen將是無定義的。,② 第5行(setq cock 1)若改寫在第3行(setq hen 1 cock 1),雖然沒,有
70、語法錯誤,但內(nèi)層循環(huán)cock的值第一次從1增加到32后,就固,定為32,出現(xiàn)了算法錯誤。,③ 程序的第12行(setq cock (1+ cock))不能只寫成(1+ cock),表達(dá),式(1+ cock)返回cock+1的值,但cock的值不變,這是1+ 函數(shù)與C,語言 ++ 運(yùn)算的不同之處。,④ 第10行(print (list “母雞=” hen “ 公雞=” cock “ 小雞=” chick))若,寫成(print “母雞
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- cad二次開發(fā)
- cad二次開發(fā)教程
- cad二次開發(fā)學(xué)習(xí)筆記五
- cad二次開發(fā)學(xué)習(xí)筆記五
- 二次開發(fā)20120621
- cad軟件二次開發(fā)平臺實現(xiàn)技術(shù)
- CAD二次開發(fā)方法研究與實現(xiàn).pdf
- dedecms二次開發(fā)手冊
- 二次開發(fā)服務(wù)承諾
- 二次開發(fā)論(1)
- 網(wǎng)站二次開發(fā)合同
- enviidl_二次開發(fā)
- 二次開發(fā)論.pdf
- 產(chǎn)品-dede二次開發(fā)
- CAD二次開發(fā)方法研究與實現(xiàn).pdf
- 二次開發(fā)及autolisp
- excel二次開發(fā)教程
- autocad二次開發(fā)(vba)
- excel二次開發(fā)教程
- 冷沖模CAD系統(tǒng)的二次開發(fā)研究.pdf
評論
0/150
提交評論