首页 理论教育AutoCAD2014中文版函数处理简介

AutoCAD2014中文版函数处理简介

【摘要】:对一个函数来说,出现在函数体中的除局部约束变量以外的任何变量均称为全局变量。函数求值后返回最后一个表达式的求值结果11.0,前面的表达是只有副作用。apply函数可以处理内建式和用户定义两种类型的函数。trace函数为指定的一个或多个函数设置跟踪标志。

1.DEFUN函数。

在AutoLISP中,函数的定义可以有名或无名,而定义有名函数是最主要的。AutoLISP提供的特殊函数defun就是提供给用户用来定义一个有名函数的。

下面就对其中各项的意义作一说明:

defun是AutoLISP的一个特殊函数,它不对其任何变元参数求值,而仅仅查看一下变元并建立一个函数定义,以后这个定义可以用函数名来调用。

sym是所定义的函数的名称,它必须是符号原子。在程序调入内存产生了一个函数定义之后,sym将配放在系统维持的符号中。

argument是一个函数的参数表,它可有如下格式:

(形式参数1形式参数2…/局部变量1局部变量2…)

(形式参数1形式参数2…)

(/局部变量1局部变量2…)

()即空表,表示没有参数。

形式参数“参数1参数2…”在函数调用时必须用实际参数替换。符号“/”不是有效的原子分隔符,所以,它必须和前后参数用空格分开。

expr1,expr2…是任意的AutoLISP表达式,它们甚至可以是所定义函数自身的调用,以形式函数的递归定义。这些表达式是函数的定义体,它们在函数调用时将依次被求值,用于完成所需的功能。例如:

该式调入内存时将产生一个名为ADD*的函数定义,用于把一个数加10再乘以2。X为该函数的形式参数,a为局部变量。这是一个非常简单的函数定义,它只有一个形式参数和两个表达式。

和系统内部提供的函数调用形式一样,用户定义函数的调用也是函数名作为被求值表的第一个元素,实际参数作为表的其他元素,且实际参数必须和形式参数的位置、顺序与数目严格对应。在函数调用时不管有无局部变量。在遇到用户定义的函数调用时,AutoLISP的求值首先对调用表中的实际参数变元求值,用求值结果依次取代函数的形式参数调用函数定义,依次执行函数定义体中的诸表达式,并把逻辑上最后一个表达式的求值结果作为调用该函数的值返回。

例如:

函数调用可以放在程序中任何地方,当然要保证函数的返回值的类型应与调用函数所要求的数据类型相符。还可以在"Command:"提示符下、菜单文件或SCR批处理文件中调用,调用格式是一样的。也就是说,AutoLISP系统内部函数调用能放的位置,用户定义的函数也能放。

例如:

在介绍AutoLISP的基本函数时,我们已经对函数的副作用有了认识。现在让我们看看用户定义的函数调用后的副作用。当然,它的主要副作用是完成所需的功能,但和系统内部提供的函数的调用不一样,用户定义函数在调用时和调用后可能会占用AutoLISP额外的符号空间,这是由于其中定义了符号变量的缘故。下面就分析一下在调用定义的函数时其变量的变化情况。

在函数定义中,要用到两种类型的变量:局部变量和全局变量。

对一个函数定义来说,局部变量是出现在参数表argument中的变量称为局部约束变量,它包括函数的形式参数和局部变量。形式参数在函数调用时用实际参数取代,局部变量是出现在argument中的除形式参数以外的变量,它用一个左下斜杠/和形式参数隔开。实际上,从变量的作用域来讲,上述两种变量均称为局部变量,这里用不同的名称只是为了加以区别。

全局变量亦称为自由变量。对一个函数来说,出现在函数体中的除局部约束变量以外的任何变量均称为全局变量。(www.chuimin.cn)

例如:

用defun产生了一个名为vartest的函数定义,其中用了5个变量:x,y,a,b,z。x,y,a,b出现函数的参数表中,是局部约束变量,其中x,y是函数vartest的形式参数。Z对於函数vartest来说是全局变量。Vartest函数的调用如下所示:

在调用函数时没有考虑局部变量a和b。函数求值后返回最后一个表达式的求值结果11.0,前面的表达是只有副作用。

变量的作用域是指变量的值可用的范围。为了说明这个问题,让我们先看一看下面的实例:

很明显,(vartest 4.51.0)的返回值是9.5,那么,(+9.5Z)等于多少呢?也许你会很快作出结论:因为Z等于1.5,所以Z和9.5相加必等于11.0。这个结论似乎很正确。其实是错误的。上式调用返回的结果为19.0。这是因为在调用vartest后,Z的值变为9.5,而不是调用前的1.5。这里就涉及到函数变量的作用域问题。

函数的局部约束变量的外部约束值在函数调用时会被保存起来,它在函数调用前有一个值,在函数调用后又恢复了这个值,而不管在函数调用中其值是如何改变的。全局变量的约束值在函数调用时被永久的改变,而以前的值得不到恢复,而是约束到新的值。如在上面的例子中,由于Z为函数vartest的全局变量,在调用vartest函数后其值从1.5改变为9.5,而执行完函数后,新值(9.5)得到保留,原值不能够恢复。但X,Y,A,B为局部约束变量,在函数调用后,它们原先的值(即在vartest的外部约束值)得到恢复。

值得注意的是,单纯地谈论一个变量是局部约束变量或全局变量是没有意义的,只有专门指出对哪一个具体函数时,才能讨论变量是局部约束的还是全局约束的。

搞清局部约束变量和全局变量的意义以及作用域十分重要。在函数调用后需要保留调用前的值的变量不能用作全局变量。

2.APPLY函数。

apply函数将一个变元表传送到一个指定的函数。apply函数可以处理内建式(subr)和用户定义(用defun或lambda)两种类型的函数。

例如:

lambda函数定义一个无名函数。lambda函数用于定义一个无名函数。在经常使用某一表达式,而又觉得把它定义成一个新函数开销太大时,就可以使用lambda函数来完成此任务。将lambda函数定位于要使用它的位置,还可以使程序员的意图表达得更清楚。lambda函数返回它的最后那个expr的值,并且,常于apply和(或)mapcar函数连用,以便对一个表中的元素执行一个函数的操作。

例如:

4.TRACE函数。

trace辅助AutoLISP程序的调试。trace函数为指定的一个或多个函数设置跟踪标志。每次当指定的函数被求值时,给出的该函数入口的一条跟踪显示信息就会出现(按调用深度的不同进行缩排),此外,还会打印出函数的执行结果。

5.UNTRACE函数。

untrace函数是trace函数的反函数。它用于清除一个或多个指定函数的跟踪标志。

6.EVAL函数。

eval函数返回一个AutoLISP表达式的求值结果。当AutoLISP的求值遇到eval函数时,它首先对变元expr进行求值,把求值结果交给eval,eval的功能是对该结果再进行一次求值。因此,从用户的角度来说,就像expr进行了两次求值:一次对expr求值,一次对expr的值求值。Exal返回最后的求值结果。

例如: